views:

96

answers:

0

Hi,

In my controller's action method, I call a WCF service, which could return a FaultException containing a business rule violation message.

I have a BaseController that overrides the OnException method as below. Since I call the controller action using AJAX, I check if the request is AJAX and only return a Content result. If it was not an AJAX call, then a redirect would occur.

protected override void OnException(ExceptionContext filterContext)
{
    var ex = filterContext.Exception;
    Log.Error(ex.Message, ex);

    if (Request.IsAjaxRequest())
    {
        var errorMessage = BuildAjaxErrorMessage(ex);
        filterContext.Result = Content(errorMessage);
        var response = filterContext.HttpContext.Response;
        response.StatusCode = (int)HttpStatusCode.InternalServerError;
        response.ContentType = MediaTypeNames.Text.Plain;
        filterContext.ExceptionHandled = true;
        return;
    }
    ...
}

On the JavaScript side, when an error is detected, I extract the text of the error message from the XHR object's responseText, which contains the error message only (the reason for using a simple Content result).

$.ajax({
    ...
    error: function(xhr, textStatus, errorThrown) {
        // here textStatus == 'error', errorThrown == undefined
        var messageDetail = extractMessageDetail(xhr);
    }
}

function extractMessageDetail(xhr) {
    var message = "An unknown error occurred"
    if (xhr != undefined && xhr != null) {
        if (xhr.status != undefined && xhr.status == 500) {
            if (xhr.responseText != undefined) {
                message = xhr.responseText;
            }
        }
    }
    if (message != undefined && message != null) {
        // In some browsers, the responseText contains an HTML document retrieved from
        // the server and not just a plain message. We don't want this displayed, so clear it
        if (message.match(/<html/i)) {
            message = "";
        }
        // We want to hide the generic server exception and provide a more user friendly one.
        if (message.indexOf("The server was unable to process the request due top an internal error") != -1) {
            message = "An unexpected error occurred on the server";
        }
    }
    return message;
}

The issue I'm having is that this works fine on my development box. If I however try to access the setup on my development box from a box on the network, the XHR.responseText contains the generic error page that is associated with requests with a response of 500 (Internal Server Error).

Is this because I'm accessing my development box from a remote computer? Would JSONP solve this issue? Is there a better way of doing it?

How does the errorThrown parameter of the $.ajax function's error handler get populated?

Cheers,

James