4

I'm making an ASP.NET MVC call to a method via AJAX and the error throws an exception. I'd like the message of the exception to be passed back to the client, and I'd prefer not to have to catch the exception. Something like this:

[HttpPost]
public ActionResult AddUser(User user) {
  if (UserIsValid(user)) {
    return Json(new { resultText = "Success!" });
  } 
  throw new Exception("The user was invalid.  Please fill out the entire form.");
}

I'm seeing in my firebug response an HTML page

<!DOCTYPE html>
<html>
    <head>
        <title>"The user was invalid.  Please fill out the entire form."</title>
        .....

I'd like to not be forced to use a try catch block to do this. Is there a way to automatically get the jQuery $(document).ajaxError(function () {} to read in this exception message? Is this bad practice? Can I override the controller OnException? Or do I have to try/catch and return JSON?

Something like this would be nice:

$(document).ajaxError(function (data) {
    alert(data.title);        
});
Adam Levitt
  • 10,316
  • 26
  • 84
  • 145
  • I think you could use the method described [here](http://stackoverflow.com/questions/4707755/asp-net-mvc-ajax-error-handling) and decorate your controller action methods that return json with your attribute filter. – James R. Oct 29 '13 at 20:46

2 Answers2

8

You can do this with a custom filter:

$(document).ajaxError(function(event, jqxhr) {
    console.log(jqxhr.responseText);
});

-

[HttpPost]
[CustomHandleErrorAttribute]
public JsonResult Foo(bool isTrue)
{
    if (isTrue)
    {
        return Json(new { Foo = "Bar" });
    }
    throw new HttpException(404, "Oh noes...");
}

public class CustomHandleErrorAttribute : HandleErrorAttribute
{
    public override void OnException(ExceptionContext filterContext)
    {
        var exception = filterContext.Exception;
        var statusCode = new HttpException(null, exception).GetHttpCode();

        filterContext.Result = new JsonResult
        {
            JsonRequestBehavior = JsonRequestBehavior.AllowGet, //Not necessary for this example
            Data = new
            {
                error = true,
                message = filterContext.Exception.Message
            }
        };

        filterContext.ExceptionHandled = true;
        filterContext.HttpContext.Response.Clear();
        filterContext.HttpContext.Response.StatusCode = statusCode;  
        filterContext.HttpContext.Response.TrySkipIisCustomErrors = true;
    }
}

Somewhat inspired by this blogpost: http://www.prideparrot.com/blog/archive/2012/5/exception_handling_in_asp_net_mvc

Francis
  • 1,214
  • 12
  • 19
0

Rather than handle an exception that was raised by the server, why not have a flag in the JSON response?

[HttpPost]
public ActionResult AddUser(User user) {
  if (UserIsValid(user)) {
    return Json(new { success = true, resultText = "Success!" });
  } 

  return Json(new { success = false, resultText = "The user was invalid.  Please fill out the entire form." });
}
Andy T
  • 10,223
  • 5
  • 53
  • 95
  • What I'd like to do here though is not have to have an if statement. I'd like the ASP.NET framework to automatically handle the error so I don't have to write the if/else block every time. – Adam Levitt Oct 29 '13 at 20:06
  • Updated comment to remove if/else block and follow initial approach – Andy T Oct 29 '13 at 20:09
  • Right, but this is what I'm already doing. I'd like to have the ASP.NET framework automatically handle this for me and automatically set the resultText to the exception message without having to write this code. Is there a way to do it? – Adam Levitt Oct 29 '13 at 20:34