0

I have a server side action that looks like this:

namespace MyProduct.Presentation.Controllers
{
    public class FooController : Controller
    {
        public ActionResult Delete(long[] fooIds)
        {
            throw new Exception("Something went wrong.");
        }
    }
}

I make an ajax request to this controller from the client like so:

var url = '/Foo/Delete';

$.ajax(url,
{
  cache: false, async: false, type: 'POST',
  data: JSON.stringify({ fooIds: fooIdsArray }), dataType: 'json',
  contentType: 'application/json', traditional: true,
  error: OnError, success: OnSuccess
});

function OnSuccess(data, textStatus, jqXHR) {
  debugger;
}

function OnError(jqXHR, textStatus, errorThrown) {
  debugger;

  // Here, I want the text "Something went wrong", 
  // which I set as the Message property
  // of my server side exception
}

How do I get the text set as the Message property of the Exception object that was raised on the server?

The client, in this case, receives an HTML response with the HTTP Status Code 500. So, I see in Fiddler that my response looks like so:

HTTP/1.1 500 Internal Server Error
Server: ASP.NET Development Server/10.0.0.0
Date: Wed, 11 Dec 2013 07:47:26 GMT
X-AspNet-Version: 4.0.30319
Cache-Control: private
Content-Type: text/html; charset=utf-8
Content-Length: 10175
Connection: Close

<!DOCTYPE html>
<html>
    <head>
        <title>Could not delete category. This category has data associated with it. Please delete the associated data first.</title>
        <meta name="viewport" content="width=device-width" />
        <style>
         body {font-family:"Verdana";font-weight:normal;font-size: .7em;color:black;} 
         p {font-family:"Verdana";font-weight:normal;color:black;margin-top: -5px}
         b {font-family:"Verdana";font-weight:bold;color:black;margin-top: -5px}
         H1 { font-family:"Verdana";font-weight:normal;font-size:18pt;color:red }
         H2 { font-family:"Verdana";font-weight:normal;font-size:14pt;color:maroon }
         pre {font-family:"Consolas","Lucida Console",Monospace;font-size:11pt;margin:0;padding:0.5em;line-height:14pt}
         .marker {font-weight: bold; color: black;text-decoration: none;}
         .version {color: gray;}
         .error {margin-bottom: 10px;}
         .expandable { text-decoration:underline; font-weight:bold; color:navy; cursor:hand; }
         @media screen and (max-width: 639px) {
          pre { width: 440px; overflow: auto; white-space: pre-wrap; word-wrap: break-word; }
         }
         @media screen and (max-width: 479px) {
          pre { width: 280px; }
         }
        </style>
    </head>

    <body bgcolor="white">

            <span><H1>Server Error in '/' Application.<hr width=100% size=1 color=silver></H1>

            <h2> <i>Could not delete category. This category has data associated with it. Please delete the associated data first.</i> </h2></span>

            <font face="Arial, Helvetica, Geneva, SunSans-Regular, sans-serif ">

            <b> Description: </b>An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

            <br><br>

            <b> Exception Details: </b>System.Exception: Could not delete category. This category has data associated with it. Please delete the associated data first.<br><br>

            <b>Source Error:</b> <br><br>

            <table width=100% bgcolor="#ffffcc">
               <tr>
                  <td>
                      <code><pre>

Line 66:                 }
Line 67: 
<font color=red>Line 68:                 throw new Exception(errorMessage);
</font>Line 69:             }
Line 70:             catch</pre></code>

                  </td>
               </tr>
            </table>

            <br>

            <b> Source File: </b> C:\Sathyaish\Clients\ESQ\SVN\GlobalizationUI.Presentation\Controllers\CategoryController.cs<b> &nbsp;&nbsp; Line: </b> 68
            <br><br>

            <b>Stack Trace:</b> <br><br>

            <table width=100% bgcolor="#ffffcc">
               <tr>
                  <td>
                      <code><pre>

[Exception: Could not delete category. This category has data associated with it. Please delete the associated data first.]
   MyProduct.Presentation.Controllers.CategoryController.Delete(Int64[] categoryIds) in yada yada yada

</pre></code>

                  </td>
               </tr>
            </table>

            <br>

            <hr width=100% size=1 color=silver>

            <b>Version Information:</b>&nbsp;Microsoft .NET Framework Version:4.0.30319; ASP.NET Version:4.0.30319.18055

            </font>

    </body>
</html>
<!-- 
[Exception]: Could not delete category. This category has data associated with it. Please delete the associated data first.
   at MyProduct.Presentation.Controllers.CategoryController.Delete(Int64[] categoryIds) in ...yada yada yada...
Water Cooler v2
  • 32,724
  • 54
  • 166
  • 336
  • Possible duplicate [ASP.NET MVC Ajax Error handling](http://stackoverflow.com/questions/4707755/asp-net-mvc-ajax-error-handling). – Zabavsky Dec 11 '13 at 08:46
  • @Zabavsky: I am not really interested in how to solve the general problem of dealing with an error situation. Nor am I interested in alternative methods to handling the exception thrown by ASP.NET. I am aware of all the alternatives. I was just wondering what the serialized exception translates to in a jQuery XHR object. It appears as though the XHR doesn't care about the specifics of the response returned, which, in this case happens to be an HTML DOM and the value I am interested in is embedded into the DOM and I don't want to write a DOM parse routine to get to that value. – Water Cooler v2 Dec 11 '13 at 16:55

2 Answers2

5

Rather than throwing an Exception you could use the following:

return new HttpStatusCodeResult(500, "Could not delete category. This category has data associated with it. Please delete the associated data first.");

You can then access the message from the textStatus variable.

5te
  • 81
  • 3
  • Good point. I am aware of all the alternatives. I was just wondering what the serialized exception translates to in a jQuery XHR object. It appears as though the XHR doesn't care about the specifics of the response returned, which, in this case happens to be an HTML DOM and the value I am interested in is embedded into the DOM and I don't want to write a DOM parse routine to get to that value. – Water Cooler v2 Dec 11 '13 at 16:53
  • 1
    You're right, the Html response is ASP.NET specific and only intended as a visual error representation, which would be obscured by customErrors in a Live environment. An alternative would be best way to go to programmatically handle an error. – 5te Dec 12 '13 at 12:08
  • Sorry for the Necro but THIS should be the answer... I'm using telerik with toastr and this triggers the telerik onerror event. I can easily put the .xhr.statusText right in the toastr.error. Instead of throwing an exception which is ASP.NET specific... it should return a status code result. No parser required. – Patrick May 18 '18 at 19:46
2

One way to do this would be to change the return type of your action on the server to JsonResult and then wrap your method calls in a try catch. This then allows you to return the exception message as json in the event of an exception:

public JsonResult Delete(long[] fooIds)
{
    try
    {
        //make method calls
        return Json(new {});
    }
    catch(Exception ex)
    {
         return Json(new {exception = ex.message});
    }

}
James
  • 2,195
  • 1
  • 19
  • 22
  • If you write `try catch` then in ajax call `OnSuccess` method is called everytime . `OnError` method is never called – Nilesh Gajare Dec 11 '13 at 08:58
  • You can get around this by adding a success boolean parameter to the json object you return. You can then check in your javascript if your success parameter is true or false and write out the exception if it equates to false. A further option could be to use [ASP.NET Web API](http://www.asp.net/web-api/overview/getting-started-with-aspnet-web-api/tutorial-your-first-web-api) instead of a standard controller, this way your action could return an HttpResponseMessage where you set the response code manually and return the exception in the response body. – James Dec 11 '13 at 09:13
  • Good point. I am aware of all the alternatives. I was just wondering what the serialized exception translates to in a jQuery XHR object. It appears as though the XHR doesn't care about the specifics of the response returned, which, in this case happens to be an HTML DOM and the value I am interested in is embedded into the DOM and I don't want to write a DOM parse routine to get to that value. – Water Cooler v2 Dec 11 '13 at 16:53