I'm maintaining a
.NET 1.1 application, and one of the things I've been tasked with is making sure the user doesn't see any unfriendly error notifications.
I've added handlers to
AppDomain.CurrentDomain.UnhandledException, which do get called. My problem is that the standard
CLR error dialog is still displayed (before the exception handler is called).
Edit: Jeff's response was marked as the correct answer, because the link he provided has the most complete information on how to do what's required.
Oh, in WinForms you definitely should be able to get it to work. The only thing you have to watch out for is things happening on different threads.
I have an old CodeProject article here which should help:
Unhandled exception behavior in a .NET 1.x WinForms app depends on:
The default behaviour of unhandled exceptions is:
The points of contact for an unhandled exception are:
The Windows Form built-in exception handling does the following by default:
You can disable the latter behaviour by setting jitDebugging = true in App.Config. But remember that this may be your last chance to stop app termination. So the next step to catch an unhandled exception is registering for event Application.ThreadException, e.g. :
Application.ThreadException += new Threading.ThreadExceptionHandler(CatchFormsExceptions);
Note the registry setting DbgJitDebugLaunchSetting under HKEY_LOCAL_MACHINE\Software.NetFramework. This has one of three values of which I'm aware:
In Visual Studio, go to Tools>Options>Debugging>JIT to set this key to 0 or 2. But a value of 1 is usually best on an end-user's machine. Note that this registry key is acted on before the CLR unhandled exception event.
This last event is your last chance to log an unhandled exception. It's triggered before your Finally blocks have executed. You can intercept this event as follows:
AppDomain.CurrentDomain.UnhandledException += new System.UnhandledExceptionEventHandler(CatchClrExceptions);
AppDomain.UnhandledException is an event, not a global exception handler. This means, by the time it is raised, your application is already on its way down the drain, and there is nothing you can do about it, except for doing cleanup and error logging.
What happened behind the scenes is this: The framework detected the exception, walked up the call stack to the very top, found no handlers that would recover from the error, so was unable to determine if it was safe to continue execution. So, it started the shutdown sequence, and fired up this event as a courtesy to you so you can pay your respects to your already-doomed process. This happens when an exception is left unhandled in the main thread.
There is no single-point solution to this kind of error. You need to put a real exception handler (a catch block) upstream of all places where this error occurs and forward it to (for example) a global handler method/class that will determine if it is safe to simply report and continue, based on exception type and/or content.
Edit: It is possible to disable (=hack) the error-reporting mechanism built into Windows so the mandatory "crash and burn" dialog does not get displayed when your app goes down. However, this becomes effective for all the applications in the system, not just your own.
is this a console app or a winforms app? If it's a .NET 1.1 console app this is, sadly, by design -- it's confirmed by a MSFT dev in the second blog post you referenced:
BTW, on my 1.1 machine the example from MSDN does have the expected output; it's just that the second line doesn't show up until after you've attached a debugger (or not). In v2 we've flipped things around so that the UnhandledException event fires before the debugger attaches, which seems to be what most people expect.
Sounds like .NET 2.0 does this better (thank goodness), but honestly, I never had time to go back and check.
It's a WinForms app. The exceptions that are caught by Application.ThreadException work fine, and I don't get the ugly .NET exception box (OK to terminate, cancel to debug? who came up with that??).
I was getting some exceptions that weren't being caught by that and ended up going to the AppDomain.UnhandledException event that were causing problems. I think I've caught most of those exceptions and I am displaying them in our nice error box now.
So I'll just have to hope there are not some other circumstances that would cause exceptions to not be caught by the Application.ThreadException handler.