Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

fetch resolves even if 404?

Using this code :

fetch('notExists') // <---- notice      .then(         function(response)         {            alert(response.status)         }     )     .catch(function(err)     {        alert('Fetch Error : ', err);     }); 

This promise resolves.

mdn

It returns a promise that resolves to the Response to that request, whether it is successful or not.

Isn't it strange that a failed ajax request is resolved even if it goes to an non-existing resource ?

I mean - what next ? a fetch to a server which is down and still get a resolved promise ?

I know I can investigate at the ok property at the response object , but still -

Question

Why do a fetch gets resolved for a completely bad request ( non existing resource ).

BTW , jquery request , does get rejected

like image 400
Royi Namir Avatar asked Sep 02 '16 16:09

Royi Namir


People also ask

Does fetch throw error 404?

The Promise returned from fetch() won't reject on HTTP error status even if the response is an HTTP 404 or 500. Instead, it will resolve normally (with ok status set to false), and it will only reject on network failure or if anything prevented the request from completing.

Does node fetch throw errors?

According to the fetch() MDN, the Promise object returned by the fetch() call is rejected (throws an error) only when "a network error is encountered." This means that fetch() Promises do resolve despite encountering client-side HTTP errors such as 404 and do not throw errors during the fetch.


1 Answers

A fetch() call is only rejected if the network request itself fails for some reason (host not found, no connection, server not responding, etc...).

Any result back from the server (404, 500, etc...) is considered a successful request from the promise point of view. Conceptually, you made a request from the server and the server answered you so from the networking point of view, the request finished successfully.

You need to then test that successful response to see if has the type of answer you wanted. If you want a 404 to be a rejection, you could code that yourself:

fetch('notExists').then(function(response) {     if (!response.ok) {         // make the promise be rejected if we didn't get a 2xx response         const err = new Error("Not 2xx response");         err.response = response;         throw err;     } else {          // go the desired response     } }).catch(function(err) {     // some error here }); 

You could even make your own myFetch() that just does this automatically for you (converts any non-200 response status to a rejection).

What is the reason behind a resolved promise for a a completely bad request ( non existing resource / server down).

First off, server down will not generate a successful response - that will reject.

A successful response is generated if you successfully connect to the server, send it a request and it returns a response (any response). As for "why" the designers of the fetch() interface decided to base the rejection on this, it's a bit hard to say without talking to someone who was actually involved in the design of that interface, but it seems logical to me. This way the rejection tells you whether the request got through and got a valid response. It's up to your code to decide what to do with the response. You can, of course, create your own wrapper function that modifies that default behavior.

like image 98
jfriend00 Avatar answered Oct 04 '22 20:10

jfriend00