DEV Community

loading...

Error Cause in JavaScript

hemanth profile image hemanth.hm ・1 min read

Say, you have a simple function to fetch data from an endPoint and has a catch block.

const fetchData = async () => {
  return await fetch('<SOME_URL>')
    .catch(err => {
       // What shall we do with the err?
    })
}
Enter fullscreen mode Exit fullscreen mode

What can you do with the err that is captured in the catch block?

  • Throw a new Error:
 throw new Error('Failed to fetch the data: ' + err.message);
Enter fullscreen mode Exit fullscreen mode
  • Wrap and throw the error:
  const wrapErr = new Error('Download raw resource failed');
  wrapErr.cause = err;
  throw wrapErr;
Enter fullscreen mode Exit fullscreen mode
  • Throw a CustomError:
class CustomError {
    constructor(msg, cause) {
        super(msg);
        this.cause = cause;
    }
}
throw new CustomError('Download raw resource failed', err);
Enter fullscreen mode Exit fullscreen mode

Perhaps it would be helpful if the Error constructor took a cause property. In that case, the value of the cause would be assigned to the instance of that error. This would improve error chaining without requiring error wrapping.

This is what we get with the error-cause proposal now on stage-3. The proposal suggests a second argument to the Error constructor with which the casuse can be specified. So we could do something like this:


const fetchData = async (url) => {
  return await fetch(url)
    .catch(err => {
        // Notice the optional object with `cause`
        throw new Error(`Unable to fetchData from ${url}`, 
                        { cause: err });
    })
}

(async () => {
  try {
    await fetchData("https://example.com/");
  } catch (e) {
    console.log(e);
    console.log('Caused by', e.cause);
  }
  // Error: Unable to fetchData from https://example.com/
  // Caused by TypeError: Failed to fetch
})();
Enter fullscreen mode Exit fullscreen mode

Hope you like this feature! πŸ€“


@gnumanth

Discussion (6)

Collapse
ecbrodie profile image
Evan Brodie

Heads up, you got a typo before the last code example. You may want to change casuse to cause πŸ˜‰

Collapse
gokulkrishh profile image
Gokulakrishnan Kalaikovan

Interesting, so we get all browser-based error cause but what will I do with this?.

Collapse
hemanth profile image
hemanth.hm Author

If the error were thrown from deep internal methods, the thrown error may not be straightforward to debug, with the cause things like these and exceptions shall get easier to handle and trace.

Collapse
gokulkrishh profile image
Gokulakrishnan Kalaikovan

Hmmm, we will know soon once people start using it and how they utilize it.

Thread Thread
hemanth profile image
hemanth.hm Author

With AggregateError, we get breadth. With the cause property, we get depth.

Collapse
mciastek profile image
Mirek Ciastek

Great article! One thing I spotted - CustomError needs to extend Error class to make super() work.

Forem Open with the Forem app