Source:  Twitter logo

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
    })
  })
    
}

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) );
17 users liked answer #0dislike answer #017
Amir Mohammad Moradi profile pic
Amir Mohammad Moradi

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.

15 users liked answer #1dislike answer #115
Andreas Gelever profile pic
Andreas Gelever

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);
        }
    });
15 users liked answer #2dislike answer #215
Sazzadur Rahman profile pic
Sazzadur Rahman

Copyright © 2022 QueryThreads

All content on Query Threads is licensed under the Creative Commons Attribution-ShareAlike 3.0 license (CC BY-SA 3.0).