Tell me more ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

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?

share|improve this question
5  
See beckelmans post for a good example. Darins answer to this post is good but don't set the correct status code for an error. – Dan Oct 11 '11 at 9:50

3 Answers

up vote 53 down vote accepted

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
    }
});
share|improve this answer
Thanks for this, The latter was what I was looking for. So for the asp.net mvc exception, is there a specific way I need to throw it so it can be caught by the jquery error handler? – Shawn Mclean Jan 16 '11 at 20:16
@Lol coder, no matter how you throw an exception inside the controller action the server will return 500 status code and the error callback will be executed. – Darin Dimitrov Jan 16 '11 at 20:22
Thanks, perfect, just what I was looking for. – Shawn Mclean Jan 16 '11 at 20:26

After googling I write a simple Exception handing based on MVC Action Filter:

public class HandleExceptionAttribute : HandleErrorAttribute
{
    public override void OnException(ExceptionContext filterContext)
    {
        if (filterContext.HttpContext.Request.IsAjaxRequest() && filterContext.Exception != null)
        {
            filterContext.HttpContext.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
            filterContext.Result = new JsonResult
            {
                JsonRequestBehavior = JsonRequestBehavior.AllowGet,
                Data = new
                {
                    filterContext.Exception.Message,
                    filterContext.Exception.StackTrace
                }
            };
            filterContext.ExceptionHandled = true;
        }
        else
        {
            base.OnException(filterContext);
        }
    }
}

and write in globol.ascx:

 public static void RegisterGlobalFilters(GlobalFilterCollection filters)
 {
      filters.Add(new HandleExceptionAttribute());
 }

and then write this script on the layout or Master page:

<script type="text/javascript">
      $(document).ajaxError(function (e, jqxhr, settings, exception) {
                       e.stopPropagation();
                       if (jqxhr != null)
                           alert(jqxhr.responseText);
                     });
</script>

Finally you should turn on custom error. and then enjoy it :)

share|improve this answer
I can see the error in Firebug butIt is not redirecting to Error page.? – user2067567 Apr 26 at 14:20
Thanks for this! should be marked as the answer IMO as its filtering on ajax requests and inherits the correct class rather than what the HandleErrorAttribute inherits – m.t.bennett Apr 29 at 5:22

For handling errors from ajax calls on the client side, you assign a function to the error option of the ajax call.

To set a default globally, you can use the function described here: http://api.jquery.com/jQuery.ajaxSetup.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.