2
1. return Request.CreateErrorResponse(HttpStatusCode.NotFound, "No product with ID = 1");

2. var resp = new HttpResponseMessage(HttpStatusCode.NotFound) { Content = new StringContent("No product with ID = 1") };
   throw new HttpResponseException(resp);

This guideline for exception handling in WebAPI describes both of above approaches.

When should we return Request.CreateErrorResponse (#1) and when should we throw an HttpResponseException (#2)?

theGeekster
  • 6,081
  • 12
  • 35
  • 47
  • possible duplicate of [ASP.NET Web API: throw HttpResponseException or return Request.CreateErrorResponse?](http://stackoverflow.com/questions/12519561/asp-net-web-api-throw-httpresponseexception-or-return-request-createerrorrespon) – Kimberly Feb 14 '14 at 19:24
  • Did you check my reply? let me know if you have any questions. – Kiran Feb 18 '14 at 16:01

2 Answers2

1

I come to the conclusion that on client side code will have same behavior in both cases, in returning ErrorResponse or throwing ResponseException. What matters is how much information we want to send back to client and how rigidly we are going to deal with errors when they occur on server side.

So personally I decided to go the rigid way, i.e. to throw an exception when it occurs and provide short (descriptive) message to client side instead of inner details of server side exception.

And technically I selected the approach mentioned here (as accepted answer of similar question). Script from that answer...

" throw exceptions from the api controller actions and have an exception filter registered that processes the exception and sets an appropriate response on the action execution context "

In my case I went with a simple implementation, in which I created an inherited exception class HttpApiException that is always thrown back to user. For handled/expected situations my code throws it directly with appropriate Error Code and custom message. Otherwise global filter UnhandledExceptionAttribute takes care of it with default Error Code 500 and default exception message.

HttpApiException

public class HttpApiException : HttpResponseException
{
    public HttpApiException(HttpResponseMessage message) : base(message) { }

    public HttpApiException(HttpStatusCode code) : base(code) { }
}

UnhandledExceptionAttribute

public class UnhandledExceptionAttribute : ExceptionFilterAttribute 
{
    public override void OnException(HttpActionExecutedContext context)
    {
        if (!(context.Exception is HttpApiException))
        {
            throw new HttpApiException(new HttpResponseMessage(HttpStatusCode.InternalServerError) { 
                Content = new StringContent(context.Exception.Message), ReasonPhrase = "An error occured while processing the request" 
            });
        }
    }
}

Register Global Filters

GlobalConfiguration.Configuration.Filters.Add(new UnhandledExceptionAttribute());

Sample Controller Code

if (new User("hello", "world").Exists()) { 
    // do something, if there will any error that will be directed towards global filter for un-handled exceptions
}
else
    throw new HttpApiException(new HttpResponseMessage(HttpStatusCode.Unauthorized) { Content = new StringContent("Invalid user name or password.") });

Note: I don't add ANY try - catch { } in individual code blocks, because all unknown/un-handled exceptions goes to UnhandledExceptionAttribute.

Community
  • 1
  • 1
theGeekster
  • 6,081
  • 12
  • 35
  • 47
0

Prefer #1 as Request.CreateErrorResponse provides a content-negotiated error response. Example: an ajax client making a json based request would get an error response in json format enabling it to read it.

*One possibility which might come into picture is when formatters themselves are unable to write the response and throw exception when writing the con-neg response. In this a content-negotiated response might not be possible. Currently web api does not return any details in response for these kind of scenarios, but you would have the global error handling feature to enable you to log these exceptions though. Long story short, you need not worry much about this scenario as this is rare and if you are using Web API's default formatters, you should be good.

Kiran
  • 56,921
  • 15
  • 176
  • 161
  • If I consider ajax client then #1 seems winning, but at the same time if I consider my API being called from C# console application. Then does it appears bypassing an error by just returning a valid response (instead of a blocking exception thrown) ? – theGeekster Feb 14 '14 at 19:30
  • Irrespective of the kind of client, error responses always have appropriate status codes, so you could always check for that. – Kiran Feb 14 '14 at 19:32