348

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;
});
Sebastian Simon
  • 18,263
  • 7
  • 55
  • 75
prostock
  • 9,327
  • 19
  • 70
  • 118
  • 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. – Ming-Tang Dec 17 '10 at 01: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; – prostock Dec 17 '10 at 02: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 – prostock Dec 17 '10 at 02:07

8 Answers8

539

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"
}
Mike 'Pomax' Kamermans
  • 49,297
  • 16
  • 112
  • 153
UltraInstinct
  • 43,308
  • 12
  • 81
  • 104
25

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 :

user2226755
  • 12,494
  • 5
  • 50
  • 73
18

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.

ubuntugod
  • 592
  • 7
  • 16
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;
    }
  }
};
Kartik Malik
  • 460
  • 4
  • 11
3

I recommend you to use this one as a ES6 best practice. Using Error object

try {
  myResponse = JSON.parse(response);
} catch (e) {
  throw new Error('Error occured: ', e);
 }

Above answer also helpful,

Bushra Mustofa
  • 1,075
  • 7
  • 12
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.

BananaAcid
  • 3,221
  • 35
  • 38
-3

You can try this:

Promise.resolve(JSON.parse(response)).then(json => {
    response = json ;
}).catch(err => {
    response = response
});
dereli
  • 1,814
  • 15
  • 23
vivek java
  • 59
  • 6
-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);
});
Jason Clay
  • 11
  • 1
  • 5
    But this does not catch the exception thrown by the `JSON.parse` – realappie Nov 08 '17 at 10:17
  • 4
    All you need to change for this to be valid is change out `JSON.parse(...)` for `()=>JSON.parse(...)`. – John Jun 01 '18 at 20:59
  • 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);` – BananaAcid Jul 09 '23 at 03:33