Reputation: 42050
I am new to TypeScript/JavaScript and Node.js and coming from Java/Scala background.
I am writing a simple script in TypeScript
to collect some data and send them as an HTTP POST request to a server using axios
.
makePromiseToGetA()
.then((a: A) => makePromiseToGetB(a))
.then((b: B) => sendHttpRequestAxios(b))
.then((resp: AxiosResponse) => outputResponse(resp))
.catch((err: Error) => handleError(err))
Now I want to improve the error handling. Specifically, I want to handle AxiosError
using my function handleAxiosError(ae: AxiosError)
in addition to the generic error handling (function handleError
)
Now I see two options to do that:
Modify the handleError
function like this:
// pseudocode because I don't know how to code this in TypeScript
function handleError(err: Error): void {
if (err instanceof AxiosError) {
handleAxiosError(err as AxiosError);
}
... // handle Error
}
"catch" AxiosError
after sendHttpRequestAxios
, handle the error, and then re-throw it:
makePromiseToGetA()
.then((a: A) => makePromiseToGetB(a))
.then((b: B) => sendHttpRequestAxios(b).catch((ae: AxiosError) => {handleAxiosError(ae); throw ae;}))
.then((resp: AxiosResponse) => outputResponse(resp))
.catch((err: Error) => handleError(err))
How would you suggest handle AxiosError
with handleAxiosError
in addition to generic error handling using handleError
?
Upvotes: 1
Views: 425
Reputation: 1074088
Your #1 seems like a reasonable solution to me if you generally want to handle AxiosError
instances differently from other errors. The problem with #2 is that you'll end up handling the error twice: Once in the Axios-specific rejection handler and then again in handleError
.
If you don't like that instanceof
approach (in handleError
or in the rejection handler at the end), you can use nesting:
makePromiseToGetA()
.then((a: A) => makePromiseToGetB(a))
.then((b: B) =>
sendHttpRequestAxios(b)
.then((resp: AxiosResponse) => outputResponse(resp))
.catch((err: AxiosError) => handleAxiosError(ae))
)
.catch((err: Error) => handleError(err))
That takes advantage of the fact that the Axios part is the last non-rejection part of the chain. So you handle it via handleAxiosError
, converting rejection to fulfillment — but nothing uses the resulting fulfillment, so you're good. If some other error occurs, though, you end up in the final rejection handler.
Side note: It's just an example and your real code is probably more complex (though perhaps the rejection handlers aren't), but when passing a fulfillment value or rejection reason to a function as its argument, there's no need for a wrapper arrow function:
makePromiseToGetA()
.then(makePromiseToGetB)
.then((b: B) =>
sendHttpRequestAxios(b)
.then(outputResponse)
.catch(handleAxiosError)
)
.catch(handleError)
Upvotes: 1