asp.net-mvcnservicebuscqrsneventstore

How to prevent ASP.net WP from terminating on error


I have some code in my ASP.net MVC project which asynchronously dispatches a message. Under certain circumstances that code can fail and cause an unhanded exception. I don't have direct access to the code which is throwing the exception or the code which is generating the thread so I'm unable to catch and handle the error there. I have tried catching at the Application_Error level in the Global.asax but that function is only thrown for page errors and not for background errors. I also tried catching in an HTTP module by implementing OnUnhandledException but I could find no way to catch the exception and prevent the worker process from existing in there.

Is there a way to prevent these errors from being so deadly? I understand they are serious errors and should be dealt with but I would rather they not terminate the worker process for other users on other pages.

More specifics:

The message dispatcher is EventStore and I believe the issue I had in this case was that it attempted to deserialize a message which implemented ICommand from a previous version of NServiceBus. After updating to the latest beta it seems deserialization failed. Unfortunately I stupidly deleted the commit which was causing the error so I can't fully duplicate the issue.

The best way I've found so far to simulate the error is to do

   public virtual ActionResult Error()
    {
        Task.Factory.StartNew(blowup);
        return new EmptyResult();
    }
    private void blowup()
    {
        throw new Exception("snap");
    }

You'll notice the snap exception is thrown and properly processed without causing issues. However if you wait then the fact we didn't observer the exception property of the Task will eventually kill the entire application.

Tested against Cassini but similar behaviour seen on IIS 7.5.


Solution

  • The problem is that any unhandled exception causes the process to abort. This problem has nothing to do with ASP.NET.

    Hook up the unobservedtaskexception event (http://msdn.microsoft.com/en-us/library/system.threading.tasks.taskscheduler.unobservedtaskexception.aspx) to catch all exceptions (and send you and email).

    I consider it to be best-practice to hook this event plus the Application_Error event plus the Thread.UnhandledException event.