2

I'm creating an HTTP API using ASP.NET Web API. I've noticed that if an exception occurs that I haven't handled, that behaviour is very different to if I deliberately throw an HttpResponseException. This will make it hard for clients to reliably handle an error and display the "reason" message.

Eg consider this code:

[HttpPost]
public void ThisWillThrowAnError()
{
    try
    {
        var i = 0;
        var b = 1 / i; // cause divide by zero exception for testing
    }
    catch (Exception ex)
    {
        HttpResponseMessage message = new HttpResponseMessage();
        message.ReasonPhrase = "Error: " + ex.Message;
        throw new HttpResponseException(message);
    }
}

This creates a response which has the error in an HTTP header and the response code set to 500: Error: This request could not be processed. Attempted to divide by zero.

The actual response body is empty.

However if I remove the try/catch block, or if an exception occurs for which I do not manually throw an HttpResponseException, I get totally different behaviour. Although the status code is still 500, the header message just says "Internal Server Error" and the message is encoded in a JSON format like this:

{
  "Message": "An error has occurred.",
  "ExceptionMessage": "Attempted to divide by zero.",
  "ExceptionType": "System.DivideByZeroException",
  "StackTrace": " at ProjectName.Controllers (etc....)"
}

I think I prefer the latter as it gives you more info for debugging but it removes the ability to customise the message or provide a user-readable message for the problem.

Why is WebAPI inconsistent with how it handles exceptions? Am I doing something myself to cause this inconsistency? It just seems rather messy and difficult to work with and may mean that the calling application will have to be coded to handle two different types of error response :(

NickG
  • 9,315
  • 16
  • 75
  • 115
  • I guess in the latter case the framework is creating an Exception in its way, and in the former case you're creating the Exception in your way, hence the difference. You could add consistency using an `ActionFilter` attribute, similar to that described in http://www.strathweb.com/2012/10/clean-up-your-web-api-controllers-with-model-validation-and-null-check-filters – Steve Wilkes Nov 30 '12 at 12:54
  • Exception handling in Web API is a bit tricky are this point. There are also certain errors that you can't trap through filters. This [SO Q & A explains the details.](http://stackoverflow.com/questions/11474076/exception-handling-beyond-exception-filters/11953509#11953509) – Sixto Saez Nov 30 '12 at 13:38
  • `HttpResponseException` is handled specifically inside the controller pipeline: http://codebetter.com/glennblock/2012/05/24/two-ways-to-work-with-http-responses-in-apicontroller-httpresponsemessage-and-httpresponseexception/ – tugberk Nov 30 '12 at 15:43

2 Answers2

2

When creating error responses, consider using HttpRequestMessage.CreateErrorResponse to create error responses that are consistent with the ones WebAPI sends.

This blog post should hopefully help: http://blogs.msdn.com/b/youssefm/archive/2012/06/28/error-handling-in-asp-net-webapi.aspx

Youssef Moussaoui
  • 12,187
  • 2
  • 41
  • 37
0

I would use message handlers. A message handler is a class that receives an HTTP request and returns an HTTP response. So you can basically change response structure in one place, and have same response for success and failure, and for all requests in your Web Api. You can read about it in my blog post: https://www.vladopandzic.com/asp-net-web-api/building-consistent-responses-asp-net-web-api/

Vlado Pandžić
  • 4,879
  • 8
  • 44
  • 75