Wednesday 16 December 2009

Inner exception details displayed instead of wrapper exception

Wrapping an exception using the Exception (string, Exception) constructor and throwing the new exception in place of the original isn’t behaving as expected for me today: ASP.NET 3.5 displays the inner exception message in its default exception display; I expected to see the wrapper exception message. Oddly enough, details pertaining to the wrapper are logged to the Application event log.

So this:

try {
// Setup to make something go wrong
throw new Exception ("Inner exception");
}
catch (Exception ex)
{
// Wrap the inner exception and throw
// a new exception instead
throw new Exception ("wrapper exception", ex);
}

spits out this (note both the message and source error clearly pointing at the inner exception line):

Inner exception

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.Exception: Inner exception

Source Error:

Line 18: try
Line 19: {
Line 20: throw new Exception ("Inner exception");
Line 21: }
Line 22: catch (Exception ex)

Despite what the message and highlighted code reveal, the stack trace does imply the wrapper exception was involved along the way.

[Exception: Inner exception]
_Default.Page_Load(Object sender, EventArgs e) in Default.aspx.cs:20

[Exception: wrapper exception]
_Default.Page_Load(Object sender, EventArgs e) in Default.aspx.cs:24 …

Adding a second try/catch to catch any exception of type Exception and inspecting the results locates the inner exception property where I’d expect it to be. Alternatively, “swallowing” the inner exception in the original catch block and throwing a new exception using the Exception (string) constructor does just that—no sign of the inner exception. I’ve additionally tried catching different types of exception (I was originally throwing ApplicationExceptions and catch Exceptions) and constructing my own exception classes with the same effect.

Maybe I’m missing something but this seems like pretty basic stuff and a few other vaguely related search results hint that I’m not alone with this one. Of course, I can always handle all exceptions myself to prevent anything killing the application but the current approach is convenient at the moment for debugging outside production where it’s less convenient to attach a debugger or check the event logs.

If you’ve got any ideas or have come across this yourself, I’d love to hear your thoughts!

2 comments:

  1. Hi Michael

    I'm not sure I understand the problem. What you're seeing is how ASP.NET displays the exception. I don't understand how this affects handling in your own code.

    ASP.NET is merely displaying the innermost exception (i.e. the root cause of the problem). With Reflector you can see this in the implementation of System.Web.UnhandledErrorFormatter (the class responsible for rendering the default error message). The PrepareFormatter() contains a loop where the innermost non-null InnerException is extracted and displayed.

    This behaviour shouldn't affect your own error handling though. The exception hierarchy is still intact. Perhaps I've missed what you were getting at?

    ReplyDelete
  2. Hi Dario,

    It's definitely the "inconsistency" (that's what I'm calling it and I'm sticking to it!!) between what ASP.NET displays and what's going execution-wise that's bothering me. You're right: the exception hierarchy is still intact.

    Because we don't display friendly errors internally, my intention was to wrap a DirectoryNotFoundException with some additional context and specific instructions for correcting the problem. Setting up a new environment invariably throws up exceptions along the way when a specific configuration requirement isn't satisfied and this was to assist in those cases.

    As far as I'm concerned as a naive developer, I've handled the inner exception and thrown the wrapper instead; it's the wrappaer message I feel ASP.NET should be presenting to me (in this particular case ;-). If I'm after the root cause I can dissect the stack trace.

    ReplyDelete

Spam comments will be deleted

Note: only a member of this blog may post a comment.