tags:

views:

153

answers:

9

Is there any event in .Net framework which gets fired on exception. Whenever there is an exception is caught, i need to log it. So if there an event exist, i can subscribe to that and can log the exceptio in the event handler.

+2  A: 

Besides the Exception? I'd just add a call to my logging module into my catch block.

Something like:

catch(YourException ex)
{
  LogMyException(ex, [otherParamsYouNeed]);
  //Other Exception Handling
}

If you want to log the status of something regardless of success or failure, use finally{}

AllenG
A: 

Hi, look at this http://www.switchonthecode.com/tutorials/csharp-tutorial-dealing-with-unhandled-exceptions UnhandledExceptionEventHandler is what you are looking for this is with windows from but i think there is similar think for the web too
Best Regards,
Iordan

IordanTanev
The web equivalent is HttpApplication.Error http://msdn.microsoft.com/en-us/library/system.web.httpapplication.error.aspx
Jace Rhea
+1  A: 

The AppDomain class has an UnhandledException event, but I don't think that you can subscribe to any exception being throw.

Paolo Tedesco
+6  A: 

Yes - there is the UnhandledException event on the AppDomain object:

AppDomain.CurrentDomain.UnhandledException += YourHandler

FYI: You should only use these handlers as a last resort - it is far better to catch exceptions in a try catch block, although this may not always be possible (for example in the case when 3rd party code starts new threads)

Also, this event will only be fired when an exception is unhandled - to my knowledge there is no way of being notified of caught events in this way without attaching a debugger to the process.

Kragen
+1 for "you should only use these handlers as last resort", I use this to log the exception, inform the user and restart the app only. Otherwise you can get into all sorts of problems.
Matt Warren
It's not clear from the documentation, but it doesn't look as though subscribing to this event gives you any opportunity to block the closure of the AppDomain.
Steven Sudit
A: 

In ASP.NET, unhandled exceptions can be caught at the page level by handling the Page_Error event, or at the application level (in global.asax, or in an IHttpModule implementation) by handling Application Error events. These events don't give you the actual exception, so you'll need to call the server to get the exception:

    Exception ex = HttpContext.Current.Server.GetLastError();
Cylon Cat
+4  A: 

You should have a look at doing some Aspect Oriented Programming with PostSharp, you can write a simple Log attribute and apply it to your whole assembly.

All you need is something like this:

[Serializable]
public class LogAttribute : OnMethodInvocationAspect
{
   public override void OnInvocation(MethodInvocationEventArgs eventArgs)
   {
      try
      {
         eventArgs.Proceed();
      }
      catch(Exception ex)
      {
         // log exception here
      }
   }
}

and apply it to your assembly:

[assembly: Log]
public class ...

It's not everyone's cup of tea, but I've found it a very clean, neat way to avoid doing a lot of boilerplate code in my classes and frees me up to work on functionalities more related to the project itself.

Update: as Kugel pointed out in the comment, this will help you track and log any exceptions thrown during the execution of the method, but if you want to log the state internal to the method you'll need to do a little more work than this.

For instance, you might still need try/catch blocks inside your method which you could use to capture exceptions that are of interest to your class and maybe even wrap them in a custom exception object so you can start adding more useful information like an error code, etc. So long your custom exception has a suitable mechanism of setting its 'Message' property, e.g.

public class DictionaryKeyNotValidException() : Exception
{
   public DictionaryKeyNotValidException(string key)
       : base(GetMessage(key))
   {   
   }

   public ErrorEnum ErrorCode { get { return ErrorEnum.InvalidDictionaryKey; } }

   private string GetMessage(string key)
   {
      return string.Format("ERROR {0} : Invalid dictionary key encountered {1}",
                           ErrorCode.GetHashCode(), key);
   }
}

then in your log attribute, provided you're using Log4Net, you can start logging more useful information:

catch (Exception ex)
{
   // log error
   log.Error(ex);

   // handle exception, rethrow, etc.
   ...
}

Sorry this is becoming a bit long winded..

theburningmonk
Still if you want to log a state inside a method, this won't help you.
Kugel
Just be sure to include `throw;` after the logging.
Dan Bryant
A: 

To extend on the answer given by theburningmonk, you could also try using log4PostSharp. This is pre-built code that uses PostSharp to insert logging code that works with the log4net logging framework.

Amongst other things this will automatically add code to your methods that catches exceptions and logs them.

It all depends on whether you are happy to use the log4net logging framework or would prefer to do it yourself.

A: 

In vb.net, one can add a "When" qualifier to a catch statement (e.g. 'Catch Ex as ObjectDisposedException When Ex.Message.Contains("Sorry")'). This may be used for logging putposes (e.g. 'Catch Ex as Exception When LoggingFunctionThatReturnsFalse(Ex)' won't catch any exceptions, but will log them all) and seems like a feature that would have been useful in C#. Last I heard, though, the feature was only available in vb.net (not sure what would happen if one compiled code using such a feature in vb.net and decompiled to C#).

supercat
That's correct: it's one of those CLR features that C# doesn't expose. You can do something fairly similar by catching all `ObjectDisposedException`'s, checking their `Message` and rethrowing with `throw;` if it's not what you were looking for. Not sure how it compares in performance, but then again, it's an exception so who cares?
Steven Sudit
@Steven Sudit: When debugging, an uncaught exception will break execution where it is thrown; a caught-and-rethrown exception will break execution where it's rethrown.
supercat
@supercat: I can't deny that there are differences when running under a debugger, but I don't write my code so that there are ever uncaught exceptions. In the worst case, the top-level catch block logs and exits.
Steven Sudit
Oh, and as for C# support, the party line is that C# and VB will be able to do the same things eventually.
Steven Sudit
When debugging, I often find it useful to leave exceptions uncaught so the debugger will go directly to the place where the exception occurs. Release code wraps everything in a master try/catch block whenever possible (I can't do much about exceptions thrown from communications objects, since those run on their own thread).
supercat
A: 

You could put something in the Global.asax Application_Error event.

I've used this method to do exactly what you described in the original post, logging the error and emailing a notification.

Mechamonkey