Getting ASP.NET MVC action exception message on jQuery $.ajax fail error callback

While testing an app I came across an error: I passed a string parameter to an action method responsible for loading an existing object by name on the database side. The problem is that there was no such object on the database. To make things even more difficult to handle this action method returns a PartialView that gets loaded in the view side using jQuery $.ajax. So how and what should I return to the caller if an exception happens while processing the request inside that action method? That’s a good question.

I tried something like this:

public ActionResult SubCatList(string subcat)
{
    var sub = Database.GetLogSubCategory(subcat);

    if(sub == null)
    {
        throw new EntryNotFoundException(String.Format("SubCategory {0} does not exist", subcat));
    }

    var subcatItems = Database.GetListItemsForSubCategory(sub);

    return PartialView(subcatItems);
}

My intention was to get that beautiful formatted exception message inside $.ajax fail callback using the error parameter like this:

$.ajax({
        url: '/api/subcatlist/subcatlist?subcat=' + subcat,
        type: 'GET',
        cache: false,
        success: function(html)
        {
            $("body").prepend(html);

// Do something more here...
} }).fail(function(xhr, textStatus, error) { displayMessage(error, 'danger'); }); }

This definitely DOES NOT WORK out of the box! So what’s the problem? The problem is that when checking/debugging the JavaScript using Firebug or Google Chrome,  the error parameter is set with a default IIS error message: Internal Server Error for the standard 500 error code. The exception message gets populated inside the xhr parameter instead in the middle of the standard page’s HTML code used by IIS.

Looking around I found something that could help in this case:

Handling Exceptions using jQuery and ASP.NET MVC

Improving the code shared on the above post, the basic idea is to have a common JsonResult action method in a BaseController for example that sets the Response.StatusDescription directly like this:

public JsonResult ThrowJsonError(Exception e)
{
    Logger.Error(e.Message, e);

    Response.StatusCode = (int)System.Net.HttpStatusCode.BadRequest;
    Response.StatusDescription = e.Message;

    return Json(new { Message = e.Message }, JsonRequestBehavior.AllowGet);
}

Now let’s use this beauty:

public ActionResult SubCatList(string subcat)
{
    var sub = Database.GetLogSubCategory(subcat);

    if(sub == null)
    {
        return ThrowJsonError(
            new EntryNotFoundException(String.Format("SubCategory {0} does not exist", subcat)));
    }

    var subcatItems = Database.GetListItemsForSubCategory(sub);

    return PartialView(subcatItems);
}

Now that beautiful formatted exception message is populated in the error parameter in $.ajax fail callback.

Objective achieved! Hope it’s useful it the future. Happy coding and 2014 for everyone…