Reputation: 31
I have seen the three following variants of throwing errors.
var response = await api.call()
.catch((error) => {
throw error;
});
var response = await api.call()
.catch((error) => {
throw Error(error);
});
var response = await api.call()
.catch((error) => {
throw new Error(error);
});
I have tried throw new Error(error)
but a chain of async functions passing down the error resulted in:
"Error: Error: Error: Actual error message"
Which of these is recommended?
Upvotes: 1
Views: 49
Reputation: 138267
throw Error(error);
that just works because JS always executes the native constructors as constructors, even if you call them as a function. That's like semicolon insertion, while it works, I would not recommend relying on it because it is confusing and might introduce unwanted side effects. Basically, if everything is working as expected it is the same as:
throw new Error(error);
now that also makes little sense, as you lose the error
s stack trace. When an error object gets constructed, a lot of information is collected about how the error happened, which is really useful for debugging. As the error constructor expects a string as the first argument, error
gets cast to a string, it is basically:
throw new Error(error.toString());
and by stringifying, you only keep the message and lose everything else. You get back an error that occurs at the line above, which hides the place where it originated from, whereas:
throw error;
just passes the error up, which will preserve all the mandatory information.
For clarity, I personally prefer not to mix thenables and async / await, so I would do:
try {
const response = await api.call()
} catch(error) {
// Some logging, handling, etc.
throw error;
}
If you can't handle the error properly and always rethrow, it is senseless, just don't try
to catch
it. Handle it somewhere up the call stack, where you can actually handle it.
Upvotes: 1
Reputation: 18493
None of them is recommended. If you can't handle an error, don't catch it. However, if you catch some errors, you should throw the error as is so as to preserve all the debugging information:
somePromise()
.catch(reason => {
if (/* some test about the error */) {
// handles some errors
} else {
throw reason; // <- more on that on @JonasWilms' answer
}
})
Upvotes: 0