370

I’m using JSON.parse on a response that sometimes contains a 404 response. In the cases where it returns 404, is there a way to catch an exception and then execute some other code?

data = JSON.parse(response, function (key, value) {
    var type;
    if (value && typeof value === 'object') {
        type = value.type;
        if (typeof type === 'string' && typeof window[type] === 'function') {
            return new(window[type])(value);
        }
    }
    return value;
});
3
  • 4
    404 response is related to XMLHttpRequest, not JSON.parse itself. If you show me the code sippet, I may be able to help you. Commented Dec 17, 2010 at 1:54
  • 1
    data = JSON.parse(response,function (key, value) { var type; if (value && typeof value === 'object') { type = value.type; if (typeof type === 'string' && typeof window[type] === 'function') { return new (window[type])(value); } } return value; Commented Dec 17, 2010 at 2:06
  • 1
    i post something into an iframe then read back the contents of the iframe with json parse...so sometimes it's not a json string Commented Dec 17, 2010 at 2:07

8 Answers 8

568

i post something into an iframe then read back the contents of the iframe with json parse...so sometimes it's not a json string

Try this:

if (response) {
    let a;
    try {
        a = JSON.parse(response);
    } catch (e) {
        return console.error(e); // error in the above string (in this case, yes)!
    }
    // if no error, we can now keep using "a"
}
Sign up to request clarification or add additional context in comments.

4 Comments

If the try block contains more statements, you can identify the exception by e.name == "SyntaxError", provided you don't have an eval.
What if response is undefined?
@vini Then you should add an else statement to the if statement.
if i console log e ,then it is printed as string but if i say e.stackTrack, e.message, it gives me the values as well, can i parse the complete object?
26

We can check error & 404 statusCode, and use try {} catch (err) {}.

You can try this :

const req = new XMLHttpRequest();
req.onreadystatechange = function() {
    if (req.status == 404) {
        console.log("404");
        return false;
    }

    if (!(req.readyState == 4 && req.status == 200))
        return false;

    const json = (function(raw) {
        try {
            return JSON.parse(raw);
        } catch (err) {
            return false;
        }
    })(req.responseText);

    if (!json)
        return false;

    document.body.innerHTML = "Your city : " + json.city + "<br>Your isp : " + json.org;
};
req.open("GET", "https://ipapi.co/json/", true);
req.send();

Read more :

1 Comment

If it cannot parse JSON then undefined should be returned. false is a valid JSON value
19

I am fairly new to Javascript. But this is what I understood: JSON.parse() returns SyntaxError exceptions when invalid JSON is provided as its first parameter. So. It would be better to catch that exception as such like as follows:

try {
    let sData = `
        {
            "id": "1",
            "name": "UbuntuGod",
        }
    `;
    console.log(JSON.parse(sData));
} catch (objError) {
    if (objError instanceof SyntaxError) {
        console.error(objError.name);
    } else {
        console.error(objError.message);
    }
}

The reason why I made the words "first parameter" bold is that JSON.parse() takes a reviver function as its second parameter.

3 Comments

I don't understand your final if/else. If true or false, the same code runs: console.err(objError);
It just return objError,name as SyntaxError, instead of the real error part.
One thing more. It should be: console.error() not console.err()
5

if you are looking for a generalized function for this, give this a shot.

const parseJSON = (inputString, fallback) => {
  if (inputString) {
    try {
      return JSON.parse(inputString);
    } catch (e) {
      return fallback;
    }
  }
};

1 Comment

Just remember that this function has 3 return values: void, JSON.parse, and the fallback value. Personally I would remove the if statement since any failures to the JSON parsing (e.g. empty input) results in the fallback being returned.
1

This is a handy and very simple pattern:

    var blah = null
    try { blah = JSON.parse(someText) }
    catch {
        // this should never, ever happen
        // LOG A DISASTER
    }

    // now, `blah` is either the value, or null

Comments

0

Just for my own fun, I tried to create oneliners out of 2 answers from here:

let response = '{"a": 123}';
let data = (_=> {try { return JSON.parse(response); } catch(err) { return undefined; }})();
if (!data) ...404...

NOTE: return undefined; is just for completeness, as return; will also result in undefined.

let response = '{"a": 123}';
let data = await Promise.resolve(_ => JSON.parse(response)).then(f => f()).catch(err => undefined);
if (!data) ...404...

NOTE: Yeah, I don't know .. the benefits of running a function inside of a Promise just to catch its error ... seems kind of wrong to me ... but non the less an interesting idea.

Please feel free and share your thoughts on those in the comments.

Comments

-3

You can try this:

Promise.resolve(JSON.parse(response)).then(json => {
    response = json ;
}).catch(err => {
    response = response
});

Comments

-5

This promise will not resolve if the argument of JSON.parse() can not be parsed into a JSON object.

Promise.resolve(JSON.parse('{"key":"value"}')).then(json => {
    console.log(json);
}).catch(err => {
    console.log(err);
});

3 Comments

But this does not catch the exception thrown by the JSON.parse
All you need to change for this to be valid is change out JSON.parse(...) for ()=>JSON.parse(...).
yeah works this way (as mentioned, but way too long compared to try-catch): let data = await Promise.resolve(_ => JSON.parse(str)).then(f => f()).catch(err => undefined);

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.