I have a web API I'm working on using the MVC 4 Web API framework. If there is an exception, I'm currently throwing a new HttpResponseException. ie:
if (!Int32.TryParse(id, out userId))
throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.BadRequest, "Invalid id"));
This returns an object to the client that is simply {"message":"Invalid id"}
I would like to gain further control over this response to exceptions by returning a more detailed object. Something like
{
"status":-1,
"substatus":3,
"message":"Could not find user"
}
How would I go about doing this? Is the best way to serialize my error object and set it in the response message?
I've also looked into the ModelStateDictionary
a bit and have come up with this bit of a "hack", but it's still not a clean output:
var msd = new ModelStateDictionary();
msd.AddModelError("status", "-1");
msd.AddModelError("substatus", "3");
msd.AddModelError("message", "invalid stuff");
throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.BadRequest, msd));
edit
looks like a custom HttpError
is what I need. This seems to do the trick, now to make it extensible from my business layer...
var error = new HttpError("invalid stuff") {{"status", -1}, {"substatus", 3}};
throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.BadRequest, error));
Take a look at the following article. It will help you gain control over your web api exceptions and error messages: Web Api, HttpError, and the Behavior of Exceptions
These answers are way more complicated than they need to be.
That's all you need. It's also nice and easy to unit test:
I think this will do the trick:
Create a custom exception class for the business layer:
Create a static method to generate a
HttpError
from an instance ofMyException
. I'm using reflection here so I can add properties toMyException
and always have them returned w/o updatingCreate
:I currently have a custom attribute for a general exception handler. All exceptions of type
MyException
will be handled here:I'll play around with this a bit more and update as I find holes in this plan.