I'll often find myself having to handle a few api calls, and I'm not really sure what the best error handling practices are.
Below is an example of a pattern I find myself writing a lot — treating throws like returns and allowing the errors to "bubble up."
Generally, it works for me, but I'm not sure if there is a better way to handle them. Or some standard practices.
Any advice or thoughts would be appreciated!
async function someApiReq(id) {
try {
const resp = fetch('https://foo.com/api' { body: JSON.stringify(id) });
if(!resp.ok) throw resp;
return await resp.json().data
} catch(e) {
if(e instanceof ApiError) {
throw e.apiMessage
}
throw e
}
}
async function someOtherApiReq(id) {
try {
const resp = fetch('https://bar.com/api' { body: JSON.stringify(id) });
if(!resp.ok) throw resp;
return await resp.json().data
} catch(e) {
throw e
}
}
(async () => {
try {
const id = 1;
const data = someApiReq(id);
const otherData = someOtherApiReq(data.id);
console.log(otherData);
} catch(e) {
console.error(e)
}
})();
Top comments (1)
It just depends on the use-case.
Imagine you have a couple of error pages, and you want to redirect to this error page if you face any error.
You could do something like that:
You can also use the QueryString to add a parameter with a message if you feel it necessary:
That's for error handling from the functional PoV.
On the other hand, from the code and user journey PoV, using
Throw
means is stops the execution plus you always will need to catch it anywhere you're using it, so you'll need to handle it multiple places with all probability.Depending on the use-case may be better to just print an error for debugging purposes and continue the program execution, maybe adding a "retry" button in case some error occurs or retrying each few seconds programmatically after a failure.
In case you do retry the request programmatically, you need to manage the API response properly. E.g. If you got a
400 - bad request
you should not attempt the same request again See the reference.Last but not least you can manage your software functions to always return something, thus avoiding the software to stop the execution as well and providing workarounds regarding the user journeys. See the quick example below:
I didn't check if the example makes sense 100% but I think it catches the idea 🤣 neither I covered all the possibilities on the comment, I always prefer the program to continue while handling the use cases, it's better for the user experience and overall satisfaction.
Hope it helps somehow, best regards 😄