30

Could you clarify what is the best practice with Web API error management. Actually, I don't know if it is a good practice to use try catch into my Api request.

public Vb.Order PostOrderItem(Vb.Order order)
{
    if (OAuth.isValid(Request.Headers.GetValues("Token").Single()) != true)
    {
        HttpResponseMessage httpResponseMessage = new HttpResponseMessage(HttpStatusCode.Unauthorized);
        throw new HttpResponseException(httpResponseMessage);
    }
    if (!ModelState.IsValid)
    {
        HttpResponseMessage httpResponseMessage = new HttpResponseMessage(HttpStatusCode.BadRequest);
        throw new HttpResponseException(httpResponseMessage);
    }

    try
    {
        return Vb.Document.Generate(order);
    }
    catch (Exception ex)
    {
        logger.Error(ex);
        HttpResponseMessage httpResponseMessage = new HttpResponseMessage(HttpStatusCode.BadRequest);
        httpResponseMessage.Content = new StringContent(ex.Message);
        throw new HttpResponseException(httpResponseMessage);
    }

}

I have the feeling using try catch to a server side code is not a good practice because I just log my catch en re-throw an exception.

3 Answers 3

45

Error handling in Web API is considered a cross-cutting concern and should be placed somewhere else in the pipeline so the developers doesn’t need to focus on cross-cutting concerns.

You should take a read of Exception Handling in ASP.NET Web API

What happens if a Web API controller throws an uncaught exception? By default, most exceptions are translated into an HTTP response with status code 500, Internal Server Error.

and also Global Error Handling in ASP.NET Web API 2.

You should try to keep your controller lean as much as possible. Error handling like your original code will only result in duplication of code, and unnecessary concerns for the developers to be aware of. Developers should focus on the core-concern, not the cross-cutting concerns. By just focusing on the core-concern the above code will look like this:

[MyAuthentication]
[MyValidateModel]
public Vb.Order PostOrderItem(Vb.Order order)
{    
    return Vb.Document.Generate(order);
}

Why so lean?

Because :

if (OAuth.isValid(Request.Headers.GetValues("Token").Single()) != true)
{
    HttpResponseMessage httpResponseMessage = new HttpResponseMessage(HttpStatusCode.Unauthorized);
    throw new HttpResponseException(httpResponseMessage);
}

can be moved into Authentication Filters in ASP.NET Web API 2 that can be applied locally on the controller/action or globally to return a relevant response.

Model Validation in ASP.NET Web API like this

if (!ModelState.IsValid)
{
    HttpResponseMessage httpResponseMessage = new HttpResponseMessage(HttpStatusCode.BadRequest);
    throw new HttpResponseException(httpResponseMessage);
}

Can also be moved into a filter like:

public class MyValidateModelAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(HttpActionContext actionContext)
    {
        if (!actionContext.ModelState.IsValid)
        {
            actionContext.Response = actionContext.Request.CreateErrorResponse(
                HttpStatusCode.BadRequest, actionContext.ModelState);
        }
    }
}
Sign up to request clarification or add additional context in comments.

5 Comments

Thank you for this answer. Just one bonus question: what about elmah? The tools has not been updated for so long. According to what you said we don't need it anymore, right?
You can still use it. And it is till a useful tool. It compliments the strategies mentioned in the links provided in the answer as you can pass/log the errors on to elmah which sits on the periphery. the plugable nature of elmah demonstrates how it focuses on tackling cross-cutting concerns as well.
How about the code logger.Error(ex); in the question? Assume Vb.Document.Generate(order) is a database call and I would like to log the exception if happened. And return the error message to the json response.
@dc7a9163d9 that would have done in the error handlers. You consume the error and return a user friendly json response. Check the link provided about exception handling.
While good advice, this answer is too vague IMO. Yes, it's a cross-cutting concern. Yes, it should be placed outside of the controller action. But this advice applies to any API framework. This question is specifically about ASP.NET Web API. The answer might be in the links, but link-only answers are no good. The rest of the answer about keeping controllers lean could be removed completely IMO.
26

Please refer to this link Exception Handling in ASP.NET Web API - A Guided Tour. There are 4 level exception handling pipeline:

  • Level 1 - HttpResponseException
  • Level 2 - Exception Filters
  • Level 3 - Logging
  • Level 4 - Exception Handlers

Web API provides us a great deal of flexibility in terms of exception handling. To recap:

  • Use HttpResponseException or the shortcut methods to deal with unhandled exceptions at the action level.
  • Use Exception Filters to deal with particular unhandled exceptions on multiple actions and controllers.
  • Use ExceptionLogger to log any unhandled exception.
  • Use Exception Handlers (one per application) to deal with any unhandled exception application-wide.

Comments

0

There are a number of methods, each one step further up the logical object graph;

This article lists them all; http://www.codeproject.com/Articles/850062/Exception-handling-in-ASP-NET-MVC-methods-explaine

I find it useful to use one of the higher level methods in order to avoid duplicate code.

1 Comment

This is about MVC, not Web API.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.