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
.