I really liked @tjvantoll article Handling Failed HTTP Responses With fetch(). The one thing I found annoying with it, though, is that response.statusText
always returns the generic error message associated with the error code. Most APIs, however, will generally return some kind of useful, more human friendly message in the body.
Here's a modification that will capture this message. The key is that rather than throwing an error, you just throw the response and then process it in the catch
block to extract the message in the body:
fetch("/api/foo")
.then( response => {
if (!response.ok) { throw response }
return response.json() //we only get here if there is no error
})
.then( json => {
this.props.dispatch(doSomethingWithResult(json))
})
.catch( err => {
err.text().then( errorMessage => {
this.props.dispatch(displayTheError(errorMessage))
})
})
Frankly, I'm horrified that JavaScript let's you throw some random value, rather than an error, but hey, when in Rome...
This post has been really helpful guys!
Here's my take on a solution that works very well with various types of data. This is similar to @incorelabs, but with my own sick wicked twist.
So to give you some background, I created an API that handles errors and returns an error as an object as many APIs do.
Example error response from server:
The problem with the other solutions is that I'm not able to throw and return the same error object, I can only reject and return strings that are not entirely helpful and really vague. So I decided to modify the response to first include the status code, text, etc. Here's the complete solution
The expected response will always be (Example):
I've tested this with various APIs and it works so far in all cases Also, I'm using fetch from the
isomorphic-unfetch
package in a NextJS application.Hope this helps someone!