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?
})
}
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);
- Wrap and throw the error:
const wrapErr = new Error('Download raw resource failed');
wrapErr.cause = err;
throw wrapErr;
- Throw a
CustomError
:
class CustomError {
constructor(msg, cause) {
super(msg);
this.cause = cause;
}
}
throw new CustomError('Download raw resource failed', err);
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
})();
Hope you like this feature! π€
P.S: Error Cause is on stage 4, per 2021.10.26 TC39 meeting.
Top comments (4)
Heads up, you got a typo before the last code example. You may want to change
casuse
tocause
π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.With
AggregateError
, we get breadth. With thecause
property, we get depth.Great article! One thing I spotted - CustomError needs to extend Error class to make super() work.