Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fetch API error handling

I want to display error message from my API, problem is that I can't reach that error if I check for response.ok, it returns Fetch error, not the one from API..

If I don't use if(response.ok)... it returns the error from API but it dispatches the success action.

Here is the example, login action:

export const signIn = data => dispatch => {
  dispatch({ 
    type: SIGN_IN
    }) 
  fetch(API_URL+'/login', { 
   method: 'POST',
   headers: {
      'content-type': 'application/json'
      },
   body: JSON.stringify(data),
    })
    .then( response => {
    if (!response.ok) { throw response }
    return response.json()  //we only get here if there is no error
  })
  .then( json => {
    dispatch({
      type: SIGN_IN_SUCCESS, payload: json
    }),
    localStorage.setItem("token", 'Bearer '+json.token)
    localStorage.setItem("user", JSON.stringify(json.user))
  })
  .catch( err => {
    dispatch({
      type: SIGN_IN_FAILED, payload: err
    })
  })
    
}

This is the code for action that dispatches the right message but as success action, not as failed one..

export const signIn = data => dispatch => {
  dispatch({ 
    type: SIGN_IN
    }) 
  fetch(API_URL+'/login', { 
   method: 'POST',
   headers: {
      'content-type': 'application/json'
      },
   body: JSON.stringify(data),
    })
    .then( response => response.json())
  .then( json => {
    dispatch({
      type: SIGN_IN_SUCCESS, payload: json
    }),
    localStorage.setItem("token", 'Bearer '+json.token)
    localStorage.setItem("user", JSON.stringify(json.user))
  })
  .catch( err => {
    dispatch({
      type: SIGN_IN_FAILED, payload: err
    })
  })
    
}
like image 562
merko Avatar asked May 14 '18 12:05

merko


People also ask

How do I get the fetch error code?

To get the status code of an HTTP request made with the fetch method, access the status property on the response object. The response. status property contains the HTTP status code of the response, e.g. 200 for a successful response or 500 for a server error.

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.

What is fetch in API?

The Fetch API provides an interface for fetching resources (including across the network). It will seem familiar to anyone who has used XMLHttpRequest , but the new API provides a more powerful and flexible feature set. Note: This feature is available in Web Workers.

What are the advantages and disadvantages of fetch API?

Follow me on twitter. I share quick tips, my reading list and also about free workshop and webinars around web and mobile development everyday. Fetch API is very powerful. We can easily send Ajax request using browser fetch API. But it has its own disadvantages too. One major disadvantage is error handling when using fetch.

When does the fetch() API reject a promise?

Per MDN, the fetch () API only rejects a promise when “a network error is encountered, although this usually means permissions issues or similar.” Basically fetch () will only reject a promise if the user is offline, or some unlikely networking error occurs, such a DNS lookup failure.

How does the fetch () method work in JavaScript?

The fetch .then () callback is passed the HTTP response object when the request is completed, the function checks if the response type is JSON before parsing the response body with the response.json () method, because calling response.json () will cause an error if the response doesn't contain JSON data.

What does “network error is encountered” mean in fetch()?

“a network error is encountered, although this usually means permissions issues or similar.” Basically fetch () will only reject a promise if the user is offline, or some unlikely networking error occurs, such a DNS lookup failure. then, you can use this part of code to use non-network error handlings and make your code more readable


3 Answers

With the following solution one can handle JSON API error, Generic API error and Generic fetch error

fetch("api/v1/demo", {
    method: "POST",
    headers: {
        "Content-Type": "application/json"
    },
    body: JSON.stringify({
        "data": "demo"
    })
})
    .then(response => {
        if (!response.ok) {
            return Promise.reject(response);
        }
        return response.json();
    })
    .then(data => {
        console.log("Success");
        console.log(data);
    })
    .catch(error => {
        if (typeof error.json === "function") {
            error.json().then(jsonError => {
                console.log("Json error from API");
                console.log(jsonError);
            }).catch(genericError => {
                console.log("Generic error from API");
                console.log(error.statusText);
            });
        } else {
            console.log("Fetch error");
            console.log(error);
        }
    });
like image 125
Sazzadur Rahman Avatar answered Oct 16 '22 16:10

Sazzadur Rahman


In order to extract API message from server in case of some error, you have to use the following idiom (which doesn't lie on the surface though), see link

     fetch("http://localhost:8090/test/error", {
        method: 'GET',
        headers: {
            'Accept': 'application/json'
        }
    })
        .then(result => {
            //Here body is not ready yet, throw promise
            if (!result.ok) throw result;
            return result.json();
        })
        .then(result => {
            //Successful request processing
            console.log(result);
        }).catch(error => {
            //Here is still promise
            console.log(error);
            error.json().then((body) => {
                //Here is already the payload from API
                console.log(body);
            });
        })

Verbose - yes!, but does exactly what is needed.

like image 32
Andreas Gelever Avatar answered Oct 16 '22 17:10

Andreas Gelever


according to This Article :

Per MDN, the fetch() API only rejects a promise when

“a network error is encountered, although this usually means permissions issues or similar.”

Basically fetch() will only reject a promise if the user is offline, or some unlikely networking error occurs, such a DNS lookup failure.

then, you can use this part of code to use non-network error handlings and make your code more readable

function handleErrors(response) {
    if (!response.ok) throw new Error(response.status);
    return response;
}

fetch("API URL")
    // handle network err/success
    .then(handleErrors)
    // use response of network on fetch Promise resolve
    .then(response => console.log("ok") )
    // handle fetch Promise error
    .catch(error => console.log(error) );
like image 19
Amir Mohammad Moradi Avatar answered Oct 16 '22 16:10

Amir Mohammad Moradi