ASP.NET MVC Ajax Error handling

Shawn Mclean picture Shawn Mclean · Jan 16, 2011 · Viewed 122.4k times · Source

How do I handle exceptions thrown in a controller when jquery ajax calls an action?

For example, I would like a global javascript code that gets executed on any kind of server exception during an ajax call which displays the exception message if in debug mode or just a normal error message.

On the client side, I will call a function on the ajax error.

On the server side, Do I need to write a custom actionfilter?

Answer

Darin Dimitrov picture Darin Dimitrov · Jan 16, 2011

If the server sends some status code different than 200, the error callback is executed:

$.ajax({
    url: '/foo',
    success: function(result) {
        alert('yeap');
    },
    error: function(XMLHttpRequest, textStatus, errorThrown) {
        alert('oops, something bad happened');
    }
});

and to register a global error handler you could use the $.ajaxSetup() method:

$.ajaxSetup({
    error: function(XMLHttpRequest, textStatus, errorThrown) {
        alert('oops, something bad happened');
    }
});

Another way is to use JSON. So you could write a custom action filter on the server which catches exception and transforms them into JSON response:

public class MyErrorHandlerAttribute : FilterAttribute, IExceptionFilter
{
    public void OnException(ExceptionContext filterContext)
    {
        filterContext.ExceptionHandled = true;
        filterContext.Result = new JsonResult
        {
            Data = new { success = false, error = filterContext.Exception.ToString() },
            JsonRequestBehavior = JsonRequestBehavior.AllowGet
        };
    }
}

and then decorate your controller action with this attribute:

[MyErrorHandler]
public ActionResult Foo(string id)
{
    if (string.IsNullOrEmpty(id))
    {
        throw new Exception("oh no");
    }
    return Json(new { success = true });
}

and finally invoke it:

$.getJSON('/home/foo', { id: null }, function (result) {
    if (!result.success) {
        alert(result.error);
    } else {
        // handle the success
    }
});