I canĀ“t find a Application.ThreadException event to listen to on my WCF service. I suppose that this is for WinForms so is there a ThreadException event for WCF services? Or will they end up in AppDomain.CurrentDomain.UnhandledException?
The Application.ThreadException event is only used to "to handle otherwise unhandled exceptions that occur in Windows Forms thread" (emphasis added, MSDN), so it isn't of much help in a WCF service.
Your best bet is to indeed use AppDomain.CurrentDomain.UnhandledException. Note however, that you cannot prevent the process from exiting. This event merely allows you to do some logging or error reporting, before "the system default handler reports the exception to the user and terminates the application." (MSDN).
You many also want to implement your own IErrorHandler. Also, checkout this blog entry about some WCF error handling best practices, while your at it.
It looks like you'll need to implement IErrorHandler:
http://msdn.microsoft.com/en-us/library/system.servicemodel.dispatcher.ierrorhandler.aspx
Then register your handler with your ServiceHost:
http://msdn.microsoft.com/en-us/library/system.servicemodel.dispatcher.channeldispatcher.errorhandlers.aspx
It looks like you can also wire up the IErrorHandlers using a custom attribute as described here: http://msdn.microsoft.com/en-us/library/ms751439.aspx
It depends on your client framework.
WCF faults get thrown as exceptions on the client side, so handle them like any other global exception handler:
Winforms uses
Application.ThreadException
WPF uses:
Application.DispatcherUnhandledException
As Christian states, these are only for exceptions thrown on the "GUI" thread, but WCF will marshal callbacks on a duplex service to these by default I think.
Related
Sure, we must avoid catching and attempting to handle AccessViolationExceptions(AVEs). However, in my current case, the exception is thrown from a COM+ managed component which terminates the process that threw the exception, therefore, cleaning up correctly. However, a windows service, hosting WCF, that consumes said COM+ component receives the bubbled up AVE causing the service crash.
The IErrorHandlers in place don't seem to fire/detect AVEs.
Is there any way to enable WCF IErrorHandlers to catch AVEs?
As a variant you can try to add a handler on AppDomain.CurrentDomain.UnhandledException where you can restart a service again.
Or, you can run your main win_service in one ('Main')AppDomain and host the WCF service in another ('Sub')AppDomain. In such way you can unloaded(reload) the sub-proccess without affecting the main process.
It is not possible for IErrorHandlers to catch exceptions similar to AccessViolationExceptions (SEHExceptions).
First some background: I have a multi-threaded WinForms application that is doing interop to native dlls. This application crashes sometimes with unhandled exception and we are trying to investigate why does it happen. In order to facilitate it, I am creating a global exception handler and I plan to generate process dumpfile from it.
Now coming towards question: as of now this application has handler for Application.ThreadException but it still crashes with unhandled exception. I am thinking of adding a handler for AppDomain.UnhandledException also although I am not sure if its going to help. Are there any possible unhandled exception in this scenario that will not be caught by Application.ThreadException?
Yes, Application.ThreadException can only trap exceptions that are raised in the UI thread. In code that's run due to Windows notifications. Or in technical terms, the events that are triggered by the message loop. Most any Winforms event fit this category.
What it does not trap are exceptions raised on any non-UI thread, like a worker thread started with Thread.Start(), ThreadPool.QueueUserWorkItem or a delegate's BeginInvoke() method. Any unhandled exception in those will terminate the app, AppDomain.UnhandledException is the last gasp.
Going further down-hill, hardware exceptions that are raised in an unmanaged thread by native code that never made any managed CLR call can not be detected with any CLR mechanism. An AccessViolation (exception code 0xc0000005) is the most common cause of death. The only way to trap those is through the Windows API, SetUnhandledExceptionFilter(). This is hard to get right.
You can disable Application.ThreadException with Application.SetUnhandledExceptionMode(). Which is a wise thing to do, giving the user the Continue option doesn't make a lot of sense. Now all exceptions in managed threads behave the same, use AppDomain.UnhandledException to log them.
Application.ThreadException will only be raised for unhandled exceptions on WinForms UI threads (see here.) Adding a handler for AppDomain.UnhandledException could help in this case (though with some caveats, as described in the remarks section here.)
I highly recommend that you use the OS minidump generation instead of your own. This is for several reasons:
Generating a minidump from within the same process is extremely problematic and not always possible.
By the time ThreadException or UnhandledException is started, the exception stack has already been unwound. Generating a minidump at that point will just point you to the handler, not the source of the exception.
If your app is in the field, use WER. If you're doing in-house testing, use ProcDump. You can also just copy the minidump file while the Error Reporting dialog is active.
P.S. There are some exceptional conditions - most notably when doing p/Invoke - where neither ThreadException nor UnhandledException will work.
P.P.S. If you have a debuggable scenario, then try turning on the Managed Debugging Assistants relating to p/Invoke.
I am currently developing a .NET application completely modular, in which:
There is the host applicaiton that loads module DDLs. The module DDLs have forms that can be opened several times.
You can unload the application domain. This will cause all the opened forms of the module to be closed.
What I want to do is to, when an unhandled exception happens in the module, the application should unload the DDL of that module and prevent the Host to crash.
I tried to use the AppDomain.UnhandledException Event, which has a handler assigned to it right after the creation of the
AppDomain as follows:
// Creates the ApplicationDomain
this._applicationDomain = AppDomain.CreateDomain(this.AppDomainName);
this._applicationDomain.UnhandledException += new UnhandledExceptionEventHandler(_applicationDomain_UnhandledException);
The problem is: that the handler is never called. Microsoft says here that
For example, suppose a thread starts in application domain "AD1", calls a method in application domain "AD2", and from there calls a method in application domain "AD3", where it throws an exception. The first application domain in which the UnhandledException event can be raised is "AD1". If that application domain is not the default application domain, the event can also be raised in the default application domain.
Even after I assign the handler, the exception still goes to
Application.Run(new HostForm());
I suppose that, if I created a new message loop for each module's form it would work, because then the thread in which the form would be running would be a separated thread, but it seems to be a stupid solution.
Another idea I had was to use than the AppDomain.UnhandledException Event of the default application domain, but how can I then:
Discover the AppDomain of origin and therefore the module to unload?
Prevent the Application to die? (I tried doing this and the e.IsTerminating comes with true value and the exception is still caught in the
Anyone? Please, I really need it.
There's a reasonably good explanation (with supporting links) about why the AppDomain.CurrentDomain.UnhandledException handler doesn't suppress unhandled exceptions here. The MSDN article you linked to also describes this behaviour just below the part you quoted.
In the .NET Framework versions 1.0 and 1.1, an unhandled exception
that occurs in a thread other than the main application thread is
caught by the runtime and therefore does not cause the application to
terminate. Thus, it is possible for the UnhandledException event to be
raised without the application terminating. Starting with the .NET
Framework version 2.0, this backstop for unhandled exceptions in child
threads was removed, because the cumulative effect of such silent
failures included performance degradation, corrupted data, and
lockups, all of which were difficult to debug.
So even if you could get the event to fire, it isn't likely to satisfy your requirement that the application not be terminated shortly afterwards. The UnhandledException handler is really only there to give you one last chance to log important information before the application is terminated.
The most resilient applications (Google Chrome for instance) will use full process isolation to ensure anything that goes wrong in a plugin tears down the external plugin host, not the main application. I've used this mechanism myself to create an application similar to the one you describe, and even went to the extent of creating sandboxed AppDomain's inside each external plugin host to ensure plugins couldn't delete critical files if the main application was elevated.
There's a really good article here that describes isolation techniques in detail and reiterates that the AppDomain plugin system isn't the best option due to the UnhandledException problem. If you're serious about a fault tolerant plugin architecture I'd recommend implementing full process isolation as described in that last article.
I'm trying to create a top level exception capture for a debug version of some real-time data capture software and was wondering if there was a top-level exception handler similar to Application.ThreadException that captures ALL exceptions, not just unhandled/trapped ones.
Thanks in advance
If you only want to be notified of all exceptions, you can use the AppDomain.FirstChanceException event.
Note: This is only available in .NET 4.0.
ALL exceptions inherit System.Exception. This would be your top-level that you can trap on.
I'm trying to implement an IErrorHandler in my WCF service in order to log every exception that hits the service boundary before it's passed to the client. I already use IErrorHandlers for translating Exceptions to typed FaultExceptions, which has been very useful. According to the MSDN for IErrorHandler.HandleError(), it's also intended to be used for logging at the boundary.
The problem is, the HandleError function isn't guaranteed to be called on the operation thread, so I can't figure out how to get information about what operation triggered the exception. I can get the TargetSite out of the exception itself, but that gives me the interior method instead of the operation. I could also parse through the StackTrace string to figure out where it was thrown, but this seems a little fragile and hokey. Is there any consistent, supported way to get any state information (messages, operationdescription, anything) while in the HandleError function? Or any other ways to automatically log exceptions for service calls?
I'm looking for a solution to implement on production, using my existing logging framework, so SvcTraceViewer won't do it for me.
Thanks.
I ended up putting the logging in IErrorHandler.ProvideFault() instead of IErrorHandler.HandlerError(). The ProvideFault call is made in the operation thread, so I can use OperationContext.Current to get some information to log.
I use the IErrorHanlder in the same way that you describe, but not for logging. Instead on service classes (WCF or not) I use an interceptor as described here. I believe that this technique will capture the information you are interested in.
You could stash any context information you need to log in the Exception's Data dictionary in the ProvideFault method which is called on the operation thread...then reference it in the HandleError method for logging purposes.
Have you used the Service Trace Viewer?
The ProvideFault() operations is being called on the incoming call thread and the client is still blocked waiting for response. I don't think it is good idea to add a lengthy process(like logging) inside this method. That is why they exposed another operation HandleError whch gets called on a separate worker thread.
But I understand your situation. Please share if you found a solution other than logging inside ProvideFault.
What about creating an instance and saving the request message on that instance?