2

I have the following code that calls an API, and caches the result (so it be used multiple times):

var requestCache = {};
function LoadDataFromApi(apiUrl) {
    if (!requestCache[apiUrl]) {
        requestCache[apiUrl] = $.ajax({
            type: 'GET',
            url: apiUrl,
            dataType: "json"
        });
    }
    return requestCache[apiUrl];
}

On occasions, the API throws an exception, which I'm trying to catch and display. According to the Firefox debugger, when an exception occurs, the response data looks like this:

{
   "Message":"An error has occurred.",
   "ExceptionMessage":"Invalid object name 'Foo_Bar'.",
   "ExceptionType":"System.Data.SqlClient.SqlException",
}

From the JQuery documentation, I see there's a statusCode object within $.ajax, but I cannot successfully implement this. An answer here is close, but doesn't actually retrieve the exception message.

From various searches today, I've got this far, but the JSON doesn't parse, and I don't know where the problem lies because the JSON parses okay when used elsewhere:

function LoadDataFromApi(apiUrl) {
    if (!requestCache[apiUrl]) {
        requestCache[apiUrl] = $.ajax({
            type: 'GET',
            url: apiUrl,
            dataType: "json",
            statusCode: {
                500: function (json) {
                    var j = JSON.parse(json);
                    alert(j.Message);
                }
            }
        });
    }
    return requestCache[apiUrl];
}

I'd be grateful if anyone could spot the issue in my code please?

EvilDr
  • 8,943
  • 14
  • 73
  • 133
  • 1
    What HTTP status code is your API returning when it returns that error JSON? 200 OK? Or 500 server error or some other status code? If it's returning an HTTP 200 OK but with that "error" JSON payload, then you just have to inspect the data that you're getting back and look to see if it has the relevant array keys that indicate it's an error response, and handle it accordingly. – dossy Oct 12 '18 at 00:12
  • It returns JSON regardless, but 500 on error and 200 on success. – EvilDr Oct 12 '18 at 05:55
  • If you're using the promise-based interface of `$.ajax` then you define your error handler using `Promise.catch()` - like `$.ajax({...}).catch(function() { /* whatever you want to do with the error */ });` – dossy Oct 12 '18 at 20:21

2 Answers2

0

Can we please go over

public class theException
{
    public string Message { get; set; }
    public string ExceptionMessage { get; set; }
    public string ExceptionType { get; set; }
}

public class EvilDrController : ApiController
{
    public theException GetContrivedException()
    {
        var exception = new theException
        {
            ExceptionMessage = "Invalid object name 'Foo_Bar'.",
            ExceptionType = "System.Data.SqlClient.SqlException",
            Message = "An error has occured"
        };
        return exception;
    }
}

html file or cshtml

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>EvilDr</title>
</head>
<body>

    <div>
        <h2>Parse JSON</h2>
    </div>
    <script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-2.0.3.min.js"></script>
    <script>
        //or whatever uri you want
        var uri = 'api/evildr';

        $(document).ready(function () {
            // Send an AJAX request
            $.getJSON(uri)
                .done(function (data) {
                    var j = JSON.stringify(data)
                    alert(j)
                });
        });
    </script>
</body>
</html>
kblau
  • 2,094
  • 1
  • 8
  • 20
0

I finally figured it out, after much searching, thanks to this answer.

The problem was here:

500: function (json) {

It turns out that although the API returns JSON data, JQuery wraps this up in an jqXHR object, which has a number of properties.

The JSON data I expected is contained inside the responseText property of the jqXHR object, so that needs parsing first. The complete solution is therefore:

function LoadDataFromApi(apiUrl) {
    if (!requestCache[apiUrl]) {
        var result = $.ajax({
            type: 'GET',
            url: apiUrl,
            dataType: "json",
            statusCode: {
                // JQuery now has an jqXHR containing all the data we need regarding any success/failures (as we can address multiple status codes here)
                500: function (xhr) {
                    // Parse the JSON data we expected
                    var err = JSON.parse(xhr.responseText);
                    // Display the error data
                    console.log('Message:' + err.Message);
                    console.log('ExceptionMessage:' + err.ExceptionMessage);
                    console.log('ExceptionType:' + err.ExceptionType);
                },
                200: function (xhr) {
                    // console.log('success');
                    // var goodData = JSON.parse(xhr.responseText);
                }
            }
        });
        // This line would generally go in success, but I need to re-use the data regardless of the status code
        requestCache[apiUrl] = result;
    }
    return requestCache[apiUrl];
}
EvilDr
  • 8,943
  • 14
  • 73
  • 133