Fetch API обработка ошибок - PullRequest
0 голосов
/ 14 мая 2018

Я хочу отобразить сообщение об ошибке из моего API, проблема в том, что я не могу получить эту ошибку, если я проверяю на response.ok, она возвращает ошибку Fetch, а не ту из API ..

Если я не использую if(response.ok)..., он возвращает ошибку от API, но отправляет успешное действие.

Вот пример, действие входа в систему:

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

Это код действия, которое отправляет правильное сообщение, но не как неудачное, а как успешное действие.

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

Ответы [ 2 ]

0 голосов
/ 18 июня 2019

Чтобы извлечь сообщение API с сервера в случае какой-либо ошибки, вы должны использовать следующую идиому (которая не лежит на поверхности), см. ссылка

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

Подробно - да !, но делает именно то, что нужно.

0 голосов
/ 14 мая 2018

согласно Эта статья :

За MDN API fetch() отклоняет обещание только тогда, когда

«сеть ошибка, хотя это обычно означает проблемы с разрешениями или подобный. ”

В основном fetch() отклонит обещание, только если пользователь находится в автономном режиме или возникает какая-то маловероятная ошибка сети, например DNS ошибка поиска.

затем вы можете использовать эту часть кода, чтобы использовать не-сетевую обработку ошибок и сделать ваш код более читабельным

function handleErrors(response) {
    if (!response.ok) throw 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) );
...