HttpErrorHandler not catching DelegatingHandler errors- preview 5

Topics: Web Api
Sep 16, 2011 at 4:37 AM
Edited Sep 16, 2011 at 4:38 AM

Hi there,

I've updated our app to preview 5. So far all is working great.
One problem I was looking forward to solve is to be able to use constructor injection in ErrorHandlers, which is now easily possible. ;-)

However I see that my ErrorHandler is not being called when an exception ocurrs during execution of a DelegatingHandler. Other errors, such as 404's, do get passed on to my ErrorHandler.
Since the logic in some of our MessageHandlers is quite complex, I would like to be able to log any exception that they might generate.
So far I have not found a way to catch these exceptions. Of course I could add a try/catch in each DelegatingHandler, but I would like to avoid this if possible.

If I have something like:

protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)

{throw new InvalidOperationException("Sb testing here"); ... }

Where is the best/recommended location to catch this exception? 

Sep 16, 2011 at 5:30 AM

Message handlers run before the dispatcher (which is where the error handler sits) which is why your error handler isn't called. Normally there is no reason to throw exceptions inside message handlers as you can just generate a response and return it right then and there.

The simplest way to do this is to write a message handler “logger” that looks for the result of a task and logs if it didn’t complete successfully. You can even set it to only run on Task failures -- something like:

        protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {
            return base.SendAsync(request, cancellationToken).ContinueWith(
                (task) =>
                {
                    /// log the message
                    var headerValue = Interlocked.Increment(ref offset);
 
                    // return our own HTTP response
                    return new HttpResponseMessage(HttpStatusCode.InternalServerError) {RequestMessage = request};
                }, TaskContinuationOptions.OnlyOnFaulted);
        }

If it is hooked in as the first (as in closest toward the network) then it will see anything happening above.

Thanks,

Henrik