I've found a method using reflection (and got it's MethodInfo). How can I invoke it without getting TargetInvocationException when exceptions are thrown?
Update
I'm creating a command implementation where the commands are handled by classes which implemement
public interface ICommandHandler<T> where T : class, ICommand
{
public void Invoke(T command);
}
Since there is one dispatcher which takes care of find and map all handlers to the correct command I can't invoke the methods directly but by using reflection. Something like:
var handlerType = tyepof(IHandlerOf<>).MakeGenericType(command.GetType());
var method = handlerType.GetMethod("Invoke", new [] { command.GetType() });
method.Invoke(theHandler, new object[]{command});
It works fine, but I want all exceptions to get passed on to the code that invoked the command.
So that the caller can use:
try
{
_dispatcher.Invoke(new CreateUser("Jonas", "Gauffin"));
}
catch (SomeSpecificException err)
{
//handle it.
}
Instead of having to catch TargetInvocationException.
(I know that I can throw the inner exception, but that's pretty worthless since the stack trace is destroyed)
Update2
Here is a possible solution..
But it seems more like a hack. Aren't there a better solution? Maybe with expressions or something?
Create a Delegate from the MethodInfo (through one of the overloads of Delegate.CreateDelegate) and invoke that instead. This won't wrap any exception thrown by the method inside a TargetInvocationException like MethodInfo.Invoke does.
class Foo
{
static void ThrowingMethod()
{
throw new NotImplementedException();
}
static MethodInfo GetMethodInfo()
{
return typeof(Foo)
.GetMethod("ThrowingMethod", BindingFlags.NonPublic | BindingFlags.Static);
}
// Will throw a NotImplementedException
static void DelegateWay()
{
Action action = (Action)Delegate.CreateDelegate
(typeof(Action), GetMethodInfo());
action();
}
// Will throw a TargetInvocationException
// wrapping a NotImplementedException
static void MethodInfoWay()
{
GetMethodInfo().Invoke(null, null);
}
}
EDIT:
(As the OP has pointed out, DynamicInvoke won't work here since it wraps too)
Based on your update, I would just use dynamic:
((dynamic)theHandler).Invoke(command);
You can't. That's the specified way that exceptions are propagated by invoking a method via reflection. You can always catch TargetInvocationException and then throw the "inner" exception obtained via the InnerException property, if you want the effect to be the original exception being thrown.
(You'll lose the original stack trace, mind you. It's possible that there's a way to prevent that, but it's tricky. I believe there may be more support for this in .NET 4.5; I'm not sure.)
You can call Invoke on the mehtodinfo instance, but the first argument of the call is the target (The object that the method info belongs to). If you pass this and it has access to call it, you should not get the exception.
Related
I have a lot of throw new NotImplementedExceptions() throughout my whole application. For now I want to silence them and to show a custom Message Dialog instead.
For catching them I'm using:
AppDomain.CurrentDomain.FirstChanceException += (sender, eventArgs) =>
{
if(eventArgs.Exception is NotImplementedException) {
return;
}
}
But the problem is that the exception is still threw.
How can I silence the throw when I catch this type of Exception within this piece of code?
It sounds like what you want to do is to do something nicer than exploding when a method you haven't implemented is invoked. I don't believe that is possible using AppDomain.FirstChanceException or the related UnhandledException. There's a good answer here that talks a bit about why simply suppressing exceptions is undesirable.
What you could do instead is use something besides raising an exception to mark methods as not implemented, like calling a helper that displays your message, when you haven't implemented something yet. You could use #if pragmas or the ConditionalAttribute to switch to actually throwing exceptions in non-DEBUG builds, if that's desirable. It's not that uncommon to use helpers for throwing exceptions anyway (see for example ThrowHelper in the BCL, or Throw in one of my own projects), as there are some benefits to avoiding throws.
This would look like:
public void UnImplementedMethod()
{
// rather than "throw new NotImplementedException("some message")"
MyHelper.NotImplemented("some message");
}
// ....
static class MyHelper
{
[Conditional("DEBUG")]
public static void NotImplemented(string msg)
{
#if DEBUG // can use whatever configuration parameter
MessageBox.Show("Not Implemented: "+ msg);
#else
throw new NotImplementedException(msg);
#endif
}
}
You can use generic parameters to handle unimplemented methods that have non-void returns, though you have to decide what to actually return if you don't throw an exception. With this pattern you can do whatever you'd like, and still easily find places that haven't been implemented.
Apparently, some exceptions may just get lost while using nested using statement. Consider this simple console app:
using System;
namespace ConsoleApplication
{
public class Throwing: IDisposable
{
int n;
public Throwing(int n)
{
this.n = n;
}
public void Dispose()
{
var e = new ApplicationException(String.Format("Throwing({0})", this.n));
Console.WriteLine("Throw: {0}", e.Message);
throw e;
}
}
class Program
{
static void DoWork()
{
// ...
using (var a = new Throwing(1))
{
// ...
using (var b = new Throwing(2))
{
// ...
using (var c = new Throwing(3))
{
// ...
}
}
}
}
static void Main(string[] args)
{
AppDomain.CurrentDomain.UnhandledException += (sender, e) =>
{
// this doesn't get called
Console.WriteLine("UnhandledException:", e.ExceptionObject.ToString());
};
try
{
DoWork();
}
catch (Exception e)
{
// this handles Throwing(1) only
Console.WriteLine("Handle: {0}", e.Message);
}
Console.ReadLine();
}
}
}
Each instance of Throwing throws when it gets disposed of. AppDomain.CurrentDomain.UnhandledException never gets called.
The output:
Throw: Throwing(3)
Throw: Throwing(2)
Throw: Throwing(1)
Handle: Throwing(1)
I prefer to at least be able to log the missing Throwing(2) and Throwing(3). How do I do this, without resorting to a separate try/catch for each using (which would kinda kill the convenience of using)?
In real life, those objects are often instances of classes over which I have no control. They may or may not be throwing, but in case they do, I'd like to have an option to observe such exceptions.
This question came along while I was looking at reducing the level of nested using. There's a neat answer suggesting aggregating exceptions. It's interesting how this is different from the standard behavior of nested using statements.
[EDITED] This question appears to be closely related:
Should you implement IDisposable.Dispose() so that it never throws?
There's a code analyzer warning for this. CA1065, "Do not raise exceptions in unexpected locations". The Dispose() method is on that list. Also a strong warning in the Framework Design Guide, chapter 9.4.1:
AVOID throwing an exception from within Dispose(bool) except under critical situations where the containing process has been corrupted (leaks, inconsistent shared state, etc.).
This goes wrong because the using statement calls Dispose() inside a finally block. An exception raised in a finally block can have an unpleasant side-effect, it replaces an active exception if the finally block was called while the stack is being unwound because of an exception. Exactly what you see happening here.
Repro code:
class Program {
static void Main(string[] args) {
try {
try {
throw new Exception("You won't see this");
}
finally {
throw new Exception("You'll see this");
}
}
catch (Exception ex) {
Console.WriteLine(ex.Message);
}
Console.ReadLine();
}
}
What you are noticing is a fundamental problem in the design of Dispose and using, for which no nice solution as yet exists. IMHO the best design would be to have a version of Dispose which receives as an argument any exception which may be pending (or null, if none is pending), and can either log or encapsulate that exception if it needs to throw one of its own. Otherwise, if you have control of both the code which could cause an exception within the using as well as within the Dispose, you may be able to use some sort of outside data channel to let the Dispose know about the inner exception, but that's rather hokey.
It's too bad there's no proper language support for code associated with a finally block (either explicitly, or implicitly via using) to know whether the associated try completed properly and if not, what went wrong. The notion that Dispose should silently fail is IMHO very dangerous and wrongheaded. If an object encapsulates a file which is open for writing, and Dispose closes the file (a common pattern) and the data cannot be written, having the Dispose call return normally would lead the calling code to believe the data was written correctly, potentially allowing it to overwrite the only good backup. Further, if files are supposed to be closed explicitly and calling Dispose without closing a file should be considered an error, that would imply that Dispose should throw an exception if the guarded block would otherwise complete normally, but if the guarded block fails to call Close because an exception occurred first, having Dispose throw an exception would be very unhelpful.
If performance isn't critical, you could write a wrapper method in VB.NET which would accept two delegates (of types Action and an Action<Exception>), call the first within a try block, and then call the second in a finally block with the exception that occurred in the try block (if any). If the wrapper method was written in VB.NET, it could discover and report the exception that occurred without having to catch and rethrow it. Other patterns would be possible as well. Most usages of the wrapper would involve closures, which are icky, but the wrapper could at least achieve proper semantics.
An alternative wrapper design which would avoid closures, but would require that clients use it correctly and would provide little protection against incorrect usage would have a usage batter like:
var dispRes = new DisposeResult();
...
try
{
.. the following could be in some nested routine which took dispRes as a parameter
using (dispWrap = new DisposeWrap(dispRes, ... other disposable resources)
{
...
}
}
catch (...)
{
}
finally
{
}
if (dispRes.Exception != null)
... handle cleanup failures here
The problem with this approach is that there's no way to ensure that anyone will ever evaluate dispRes.Exception. One could use a finalizer to log cases where dispRes gets abandoned without ever having been examined, but there would be no way to distinguish cases where that occurred because an exception kicked code out beyond the if test, or because the programmer simply forgot the check.
PS--Another case where Dispose really should know whether exceptions occur is when IDisposable objects are used to wrap locks or other scopes where an object's invariants may temporarily be invalidated but are expected to be restored before code leaves the scope. If an exception occurs, code should often have no expectation of resolving the exception, but should nonetheless take action based upon it, leaving the lock neither held nor released but rather invalidated, so that any present or future attempt to acquire it will throw an exception. If there are no future attempts to acquire the lock or other resource, the fact that it is invalid should not disrupt system operation. If the resource is critically necessary to some part of the program, invalidating it will cause that part of the program to die while minimizing the damage it does to anything else. The only way I know to really implement this case with nice semantics is to use icky closures. Otherwise, the only alternative is to require explicit invalidate/validate calls and hope that any return statements within the part of the code where the resource is invalid are preceded by calls to validate.
Maybe some helper function that let you write code similar to using:
void UsingAndLog<T>(Func<T> creator, Action<T> action) where T:IDisposabe
{
T item = creator();
try
{
action(item);
}
finally
{
try { item.Dispose();}
catch(Exception ex)
{
// Log/pick which one to throw.
}
}
}
UsingAndLog(() => new FileStream(...), item =>
{
//code that you'd write inside using
item.Write(...);
});
Note that I'd probably not go this route and just let exceptions from Dispose to overwrite my exceptions from code inside normal using. If library throws from Dispose against strong recommendations not to do so there is a very good chance that it is not the only issue and usefulness of such library need to be reconsidered.
I'm using the reactive extensions for a kind of a in process message bus.
The implementation is quite simple.
Register looks like
public IDisposable Register<T>(Action<T> action) where T : IMessage
{
return this.subject
.OfType<T>()
.Subscribe(action);
}
And send simply:
private void SendMessage(IMessage message)
{
this.subject.OnNext(message);
}
However i'm now having some trouble with the exception behaviour of RX.
One an exception is thrown in a registered/subscribed action - the Observable 'stream' is broken and will not subscribe anymore.
Sine this message bus is used for two parts of the application to communicate i need to ensure that such a stream is never broken even if an unexpected exception is thrown.
If you need to ensure that the stream is never broken by an exception, then you need to have another channel for the exceptions.
This behavior is not completely unexpected. From the documentation for the IObserver<T> interface:
The OnError method, which is typically called by the provider to indicate that data is unavailable, inaccessible, or corrupted, or that the provider has experienced some other error condition.
Given this, if the stream is unavailable, corrupted, etc, you definitely want the stream to be "faulted" (this is analagous to a channel being faulted in WCF); the state is indeterminate so you can't rely on anything else that comes from the IObservable<T> implementation; so why should there be an expectation that there will be any more observations?
That said, you have a some options:
Swallow the exception
You'd have to wrap the action delegate that you pass into your Register function, like so:
public IDisposable Register<T>(Action<T> action) where T : IMessage
{
return this.subject
.OfType<T>()
.Subscribe(t => {
// Execute action
try { action(t); }
catch { }
});
}
This, of course, might not be desirable, as you might be throwing away exceptions which impact your program (or, you might know exactly what's going on here, and want to skip them), but it can be used to build on the next solution.
Provide an action to take when an exception is thrown
Using the above as the base, you can ask for an Action<T, Exception> which will be called when an exception is thrown.
public IDisposable Register<T>(Action<T> action,
Action<T, Exception> errorHandler) where T : IMessage
{
return this.subject
.OfType<T>()
.Subscribe(t => {
// Execute action
try { action(t); }
catch (Exception e) { errorHandler(t, e); }
});
}
Now, when an exception is thrown from action, it will be passed to your exception handler without breaking the stream.
The above can easily be overloaded to provide the behavior which will swallow the exception (which again, may or may not serve your purposes):
public IDisposable Register<T>(Action<T> action) where T : IMessage
{
// Call the overload, don't do anything on
// exception.
return Register(action, (t, e) => { });
}
Basically you can provide an OnError delegate on the Subscribe method. I've written a small tutorial that takes this matter into consideration (Exception Handling), quite recently on my blog : http://blog.andrei.rinea.ro/2013/06/01/bing-it-on-reactive-extensions-story-code-and-slides/
Have look at the OnError method. Basically you need to resubscribe since the Rx framework is built on the premise that a sequence is broken when an error has occured.
I'm writing a wrapper around a fairly large unmanaged API. Almost every imported method returns a common error code when it fails. For now, I'm doing this:
ErrorCode result = Api.Method();
if (result != ErrorCode.SUCCESS) {
throw Helper.ErrorToException(result);
}
This works fine. The problem is, I have so many unmanaged method calls that this gets extremely frustrating and repetitive. So, I tried switching to this:
public static void ApiCall(Func<ErrorCode> apiMethod) {
ErrorCode result = apiMethod();
if (result != ErrorCode.SUCCESS) {
throw Helper.ErrorToException(result);
}
}
Which allows me to cut down all of those calls to one line:
Helper.ApiCall(() => Api.Method());
There are two immediate problems with this, however. First, if my unmanaged method makes use of out parameters, I have to initialize the local variables first because the method call is actually in a delegate. I would like to be able to simply declare a out destination without initializing it.
Second, if an exception is thrown, I really have no idea where it came from. The debugger jumps into the ApiCall method and the stack trace only shows the method that contains the call to ApiCall rather than the delegate itself. Since I could have many API calls in a single method, this makes debugging difficult.
I then thought about using PostSharp to wrap all of the unmanaged calls with the error code check, but I'm not sure how that would be done with extern methods. If it ends up simply creating a wrapper method for each of them, then I would have the same exception problem as with the ApiCall method, right? Plus, how would the debugger know how to show me the site of the thrown exception in my code if it only exists in the compiled assembly?
Next, I tried implementing a custom marshaler that would intercept the return value of the API calls and check the error code there. Unfortunately, you can't apply a custom marshaler to return values. But I think that would have been a really clean solution it if had worked.
[return:
MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(ApiMethod))]
public static extern ErrorCode Method();
Now I'm completely out of ideas. What are some other ways that I could handle this?
Follow ErrorHandler class from the Visual Studio 2010 SDK. It existed in earlier versions, but the new one has CallWithCOMConvention(Action), which may prove valuable depending on how your API interacts with other managed code.
Of the available methods, I recommend implementing the following:
Succeeded(int)
(Failed() is just !Succeeded(), so you can skip it)
ThrowOnFailure(int)
(Throws a proper exception for your return code)
CallWith_MyErrorCode_Convention(Action) and CallWith_MyErrorCode_Convention(Func<int>)
(like CallWithCOMConvention, but for your error codes)
IsCriticalException(Exception)
(used by CallWith_MyErrorCode_Convention)
What happens if you don't check ErrorCode.SUCCESS? Will your code quickly fail and throw an exception? Can you tell which unmanaged API failed if your managed code throws? If so, consider not checking for errors and just letting the runtime throw when your unmanaged API fails.
If this is not the case, I suggest biting the bullet and following your first idea. I know you called it "frustrating and repetitive", but after coming from a project with a "clever" macro solution to a similar problem, checking return values in method calls and wrapping exceptions is the doorway to insanity: exception messages and stack traces become misleading, you can't trace the code, performance suffers, your code become optimized for errors and goes off the rails upon success.
If a particular return value is an error, thow a unique exception then. If it might not be an error, let it go and throw if becomes an error. You said you wanted to reduce the check to one line?
if (Api.Method() != ErrorCode.SUCCESS) throw new MyWrapperException("Api.Method broke because ...");
Your proposal also throws the same exception if any method returns the same "common error code". This is another debugging nightmare; for APIs which return the same error codes from multiple calls, do this:
switch (int returnValue = Api.Method1())
{
case ErrorCode.SUCCESS: break;
case ErrorCode.TIMEOUT: throw new MyWrapperException("Api.Method1 timed out in situation 1.");
case ErrorCode.MOONPHASE: throw new MyWrapperException("Api.Method1 broke because of the moon's phase.");
default: throw new MyWrapperException(string.Format("Api.Method1 returned {0}.", returnValue));
}
switch (int returnValue = Api.Method2())
{
case ErrorCode.SUCCESS: break;
case ErrorCode.TIMEOUT: throw new MyWrapperException("Api.Method2 timed out in situation 2, which is different from situation 1.");
case ErrorCode.MONDAY: throw new MyWrapperException("Api.Method2 broke because of Mondays.");
default: throw new MyWrapperException(string.Format("Api.Method2 returned {0}.", returnValue));
}
Verbose? Yup. Frustrating? No, what's frustrating is trying to debug an app that throws the same exception from every line whatever the error.
I think, the easy way is to add aditional layer.
class Api
{
....
private static ErrorCode Method();//changing Method to private
public static void NewMethod()//NewMetod is void, because error is converted to exceptions
{
ErrorCode result = Method();
if (result != ErrorCode.SUCCESS) {
throw Helper.ErrorToException(result);
}
}
....
}
Create a private property to hold the ErrorCode value, and throw the exception from the setter.
class Api
{
private static ErrorCode _result;
private static ErrorCode Result
{
get { return _result; }
set
{
_result = value;
if (_result != ErrorCode.SUCCESS)
{
throw Helper.ErrorToException(_result);
}
}
}
public static void NewMethod()
{
Result = Api.Method();
Result = Api.Method2();
}
}
Write a T4 template to do the generation for you.
Your existing code is actually really, really close. If you use an expression tree to hold the lambda, instead of a Func delegate, then your Helper.ApiCall can pull out the identity of the function that was called and add that to the exception it throws. For more information on expression trees and some very good examples, Google Marc Gravell.
I'm working with threads on a compact framework project and have code that looks something like below. When I try to step into StartThreads(), a NotSupportedException is thrown. This seems a bit wierd, why is the exception thrown on the line calling StartThreads() and not inside, and what is it that's not supported on CF? I think its ThreadStart.BeginInvoke but that's not where the exception is actually being thrown.
void SomeMethod()
{
this.StartThreads(); // <- NotSupportedException is thrown here, I can't step into this method with the debugger
}
void StartThreads()
{
ThreadStart threadStart = BeginDoStuff;
threadStart.BeginInvoke(EndDoStuff, null);
}
The BeginInvoke mechanism is not supported in CF, along with the ThreadPool.
The reason you don't see the Exception where you expect is due to the way this is implemented. I am not totally sure about the details but BeginInvoke is not a normal method (of the Delegate class) but something that is injected at runtime (just guessing that last part).
The error occurs when the JIT compiler gets to work on the StartThreads method.
delegate.BeginInvoke is not supported on the CF.
However the ThreadPool is supported. You can use the thread pool to achieve essentially the same behavior.
void SomeMethod()
{
this.StartThreads();
}
void StartThreads()
{
System.Threading.ThreadPool.QueueUserWorkItem(DoStuff);
}
if you want it to call a callback when finished I suggest you read up on the Asynchronous Programming Model