Search code examples
javascriptexceptiones6-promise

Error handling in Javascript promises(throwing errors)


I would like to do some error handling on the response received from a call I am making and then move to the catch if the specific null check is hit. Something like this:

    fetch('example.json')
        .then(response => {
            if (response.data === null) {
                //go to catch
            }
        })
        .catch(error => {
            console.error("error happened", error);
        })

What would be the best way to go about doing something like this? Any red flags with throwing an error inside a then block?


Solution

  • If you throw in a promise handler, that rejects the promise the handler returns. So:

    fetch('example.json')
        .then(response => {
            if (response.data === null) {
                throw new Error();
            }
        })
        .catch(error => {
            console.error("error happened", error);
        })
    

    What you throw will be the rejection reason the catch handler sees. It doesn't have to be an Error, but as with synchronous code, it's generally best if it is.

    But, note that A) A fetch response doesn't have a data property, and B) You need to check for HTTP success and parse the JSON that was returned.

    You probably want something like this:

    fetch('example.json')
        .then(response => {
            if (!response.ok) {
                // (I tend to use an specialized `Error` type here
                // More on my anemic blog:
                // http://blog.niftysnippets.org/2018/06/common-fetch-errors.html)
                throw new Error("HTTP error " + response.status);
            }
            return response.json();
        })
        .then(data => {
            if (data === null) {
                throw new Error("The data is null");
            })
            // ...do something with `data`...
        })
        .catch(error => {
            console.error("error happened", error);
        });
    

    In a comment on the question you've said:

    i was hoping there was a way to check this response object without having to trigger the 'extreme' measure of throwing an exception

    You do have an alternative which is basically identical in outcome: Return a rejected promise. Here's my second code block above adapted to do that:

    fetch('example.json')
        .then(response => {
            if (!response.ok) {
                // (I tend to use an specialized `Error` type here
                // More on my anemic blog:
                // http://blog.niftysnippets.org/2018/06/common-fetch-errors.html)
                return Promise.reject(new Error("HTTP error " + response.status));
            }
            return response.json();
        })
        .then(data => {
            if (data === null) {
                return Promise.reject(new Error("The data is null"));
            })
            // ...do something with `data`...
        })
        .catch(error => {
            console.error("error happened", error);
        });
    

    And as with the throw version, you don't have to use an Error, it's just best practice. It can be anything you want.