40

Possible Duplicate:
.NET - What’s the best way to implement a “catch all exceptions handler”

I have a .NET console app app that is crashing and displaying a message to the user. All of my code is in a try{<code>} catch(Exception e){<stuff>} block, but still errors are occasionally displayed.

In a Win32 app, you can capture all possible exceptions/crashes by installing various exception handlers:

/* C++ exc handlers */
_set_se_translator
SetUnhandledExceptionFilter
_set_purecall_handler
set_terminate
set_unexpected
_set_invalid_parameter_handler

What is the equivalent in the .NET world so I can handle/log/quiet all possible error cases?

Community
  • 1
  • 1
DougN
  • 4,407
  • 11
  • 56
  • 81
  • Keep in mind that there are [many ways for a process to "crash"](http://stackoverflow.com/questions/3613108/ways-for-an-unmanaged-windows-process-to-crash), each of which might require special tricks to catch - all of these are in addition to ways for a managed exception to bring down your application. One last complication is that WinForms, for example, may interfere with your attempts by catching exceptions before they reach the application's global exception handler. – Roman Starkov Oct 09 '13 at 21:35

11 Answers11

44

You can add an event handler to AppDomain.UnhandledException event, and it'll be called when a exception is thrown and not caught.

Juanma
  • 3,961
  • 3
  • 27
  • 26
  • 2
    Setting AppDomain.UnhandledException seems to work EXACTLY like calling Win32 SetUnhandledExceptionFilter. If another part of your app has installed a filter, AppDomain.UnhandledException will properly "chain" and call the other filter too. – Corey Trager Sep 26 '09 at 18:19
28

Contrary to what some others have posted, there's nothing wrong catching all exceptions. The important thing is to handle them all appropriately. If you have a stack overflow or out of memory condition, the app should shut down for them. Also, keep in mind that OOM conditions can prevent your exception handler from running correctly. For example, if your exception handler displays a dialog with the exception message, if you're out of memory, there may not be enough left for the dialog display. Best to log it and shut down immediately.

As others mentioned, there are the UnhandledException and ThreadException events that you can handle to collection exceptions that might otherwise get missed. Then simply throw an exception handler around your main loop (assuming a winforms app).

Also, you should be aware that OutOfMemoryExceptions aren't always thrown for out of memory conditions. An OOM condition can trigger all sorts of exceptions, in your code, or in the framework, that don't necessarily have anything to do with the fact that the real underlying condition is out of memory. I've frequently seen InvalidOperationException or ArgumentException when the underlying cause is actually out of memory.

Guy
  • 65,082
  • 97
  • 254
  • 325
  • 2
    I am surprised there are not more up votes on this. Juanma made a good addition with capturing the event, however, that does not cover all scenarios. The information that should be taken from this is that it is fine to break standards sometimes. Catch specific exception types with explicit functionality and have a wrapper to catch and handle anything else. If you are writing a DLL, from my experience, you should have a class inherit from exception, create your functionality, wrap your unhandled exception within the property InnerException and throw. – Anthony Mason Feb 03 '15 at 17:29
11

This article in codeproject by our host Jeff Atwood is what you need. Includes the code to catch unhandled exceptions and best pratices for showing information about the crash to the user.

Ricardo Amores
  • 4,597
  • 1
  • 31
  • 45
10

The Global.asax class is your last line of defense. Look at:

protected void Application_Error(Object sender, EventArgs e)

method

Drejc
  • 14,196
  • 16
  • 71
  • 106
6

Be aware that some exception are dangerous to catch - or mostly uncatchable,

  • OutOfMemoryException: anything you do in the catch handler might allocate memory (in the managed or unmanaged side of the CLR) and thus trigger another OOM
  • StackOverflowException: depending whether the CLR detected it sufficiently early, you might get notified. Worst case scenario, it simply kills the process.
Peli
  • 2,465
  • 16
  • 17
4

You can use the AppDomain.CurrentDomain.UnhandledException to get an event.

Mendelt
  • 36,795
  • 6
  • 74
  • 97
4

Although catching all exceptions without the plan to properly handle them is surely a bad practice, I think that an application should fail in some graceful way. A crash should not scare the user to death, and at least it should display a description of the error, some information to report to the tech support stuff, and ideally a button to close the application and restart it. In an ideal world, the application should be able to dump on disk the user data, and then try to recover it (but I see that this is asking too much).

Anyway, I usually use:

AppDomain.CurrentDomain.UnhandledException
Dario Solera
  • 5,694
  • 3
  • 29
  • 34
3

You may also go with Application.ThreadException Event.

Once I was developing a .NET app running inside a COM based application; this event was the very useful, as AppDomain.CurrentDomain.UnhandledException didn't work in this case.

petr k.
  • 8,040
  • 7
  • 41
  • 52
1

I think you should rather not even catch all Exception but better let them be shown to the user. The reason for this is that you should only catch Exceptions which you can actually handle. If you run into some Exception which causes the program to stop but still catch it, this might cause much more severe problems. Also read FAQ: Why does FxCop warn against catch(Exception)?.

hangy
  • 10,765
  • 6
  • 43
  • 63
  • 3
    Yes, but it would be nice to be able to log all info (stack trace, versions of all dependencies, maybe a screenshot) before the application dies completely... – Benjol Sep 18 '08 at 12:41
1

Be aware that catching these unhandled exceptions can change the security requirements of your application. Your application may stop running correctly under certain contexts (when run from a network share, etc.). Be sure to test thoroughly.

0

it doesn't hurt to use both AppDomain.CurrentDomain.UnhandledException Application.ThreadException

but keep in mind that exceptions on secondary threads are not caught by these handlers; use SafeThread for secondary threads if needed

Steven A. Lowe
  • 60,273
  • 18
  • 132
  • 202
  • From MSDN: If the UnhandledException event is handled in the default application domain, it is raised there for any unhandled exception in any thread, no matter what application domain the thread started in. (So in some cases all app domains may not be handled, but threads in the same app domain are certainly handled... Of course, those captured exceptions may still terminate the app.) –  May 30 '12 at 14:29
  • @ebyrob: trust MSDN, but verify ;) – Steven A. Lowe May 30 '12 at 14:31
  • I just verified I could catch both Timer and ThreadPool exceptions with the UnhandledException event. (Both resulted in a dead app though) –  May 30 '12 at 14:34
  • @ebyrob: excellent. does it work the same in .NET 1.1, 2.0...4.0? Note that this answer is 3.5 years old, so it was most likely referring to .net 2.0 – Steven A. Lowe May 30 '12 at 14:45
  • For latest patch levels seems the same in 2.0 and 4.0. From the article you link: "These threads just die, with no unhandled-exception event to trap, no warning to the user, nothing." (Which doesn't appear to be true, at least in normal circumstances, and assuming no relevant hotfix.) –  May 30 '12 at 15:15