ASP.NET MVC Ajax Error handling
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 }});
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 global.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 :)
Unfortunately, neither of answers are good for me. Surprisingly the solution is much simpler. Return from controller:
return new HttpStatusCodeResult(HttpStatusCode.BadRequest, e.Response.ReasonPhrase);
And handle it as standard HTTP error on client as you like.