3

After reading this MSDN page, I've created a global exception handler in my .net class library, for logging purposes, which looks like this:

    static void OnException(object sender, UnhandledExceptionEventArgs args)
    {
        Exception ex = (Exception)args.ExceptionObject;
        Logging.LogException(ex);
    }

But then if I throw new UnauthorizedAccessException() or throw new Exception() from a method, this does not catch it at all.

The MSDN page says:

UnhandledExceptionEventArgs provides access to the exception object and a flag indicating whether the common language runtime is terminating. The UnhandledExceptionEventArgs is one of the parameters passed into UnhandledExceptionEventHandler for the AppDomain.UnhandledException event

I believe what I'm doing falls under the AppDomain (and not ThreadException)? What am I doing wrong here?

PS. I'm trying to avoid a try-catch block, since apparently it's bad practice. This class library is called from a windows service which runs periodically so I'd rather not let it 'crash' to avoid memory leaks due to unforeseen exceptions and would prefer to monitor the event logs regularly.

Community
  • 1
  • 1
reggaemahn
  • 6,272
  • 6
  • 34
  • 59
  • This method alone does nothing. Do you subscribe to the UnhandledException event? And if your conclusion from reading the linked Q&A is _"Using try-catch is bad practice"_, you may want to read it again. – CodeCaster Jan 06 '16 at 13:38
  • Yes, that's the problem. Although since I don't have a `main` method, where should I be subscribing? As for the attached, it says that in bold. I do agree that it goes into detail but even where the answer talks about logging, it talks about logging and allowing the app to crash. I'm trying to avoid this. – reggaemahn Jan 06 '16 at 13:42
  • It says "without a good reason". Anyway you should not want to do this from a class library. It's up to the consuming application how to handle exceptions. – CodeCaster Jan 06 '16 at 13:49

2 Answers2

4

You will need to install the exception handler in the current app domain in order for it to fire:

AppDomain.CurrentDomain.UnhandledException += OnException;

Otherwise its just a method declaration that will never be called.

user957902
  • 3,010
  • 14
  • 18
  • Yes, that is how you subscribe to an event. It is however not a solution to OP's problem, even though they have accepted this answer. The `UnhandledException` event provides you merely with a _notification_ of an unhandled exception. You're not going to be able to _handle_ it there, and you most definitely don't want to do this in **library code** that OP claims to be writing, as you'll be notified of _all_ unhandled exceptions in the appdomain. – CodeCaster Jan 06 '16 at 18:10
2

You mention that you are trying to avoid a try catch, but inside your handler, that wouldn't be a bad idea:

static void OnException(object sender, UnhandledExceptionEventArgs args)
{
    try
    {
        Exception ex = (Exception)args.ExceptionObject;
        Logging.LogException(ex);
    }
    catch
    {
       // do nothing to silently swallow error, or try something else...
    }
}

...Because you don't want to explode in your error handler. Either swallow if stability is of primary importance, or try a secondary (more basic) logging method to insure that no exception falls through the cracks.

Normally, swallowing an exception silently is a poor practice, but this is inside an error handling block where failure means crashing an app.

Roger Hill
  • 3,677
  • 1
  • 34
  • 38