web-dev-qa-db-ja.com

Redux / Axiosでエラー応答422をキャッチして処理する方法は?

ユーザーのパスワードを更新するためにサーバーにPOSTリクエストを行うアクションがありますが、連鎖catchブロックでエラーを処理できません。

return axios({
  method: 'post',
  data: {
    password: currentPassword,
    new_password: newPassword
  },
  url: `path/to/endpoint`
})
.then(response => {
  dispatch(PasswordUpdateSuccess(response))
})
.catch(error => {
  console.log('ERROR', error)
  switch (error.type) {
    case 'password_invalid':
      dispatch(PasswordUpdateFailure('Incorrect current password'))
      break
    case 'invalid_attributes':
      dispatch(PasswordUpdateFailure('Fields must not be blank'))
      break
  }
})

エラーを記録すると、これが表示されます。

Error Logged

[ネットワーク]タブを確認すると、応答本文が表示されますが、何らかの理由で値にアクセスできません!

Network Tab

どこかに知らずにミスをしたことがありますか?私は別のリクエストからの他のエラーをうまく処理していますが、これを解決することはできないようです。

38
Phillip Boateng

Axiosはおそらく応答を解析しています。私のコードでこのようなエラーにアクセスします:

axios({
  method: 'post',
  responseType: 'json',
  url: `${SERVER_URL}/token`,
  data: {
    idToken,
    userEmail
  }
})
 .then(response => {
   dispatch(something(response));
 })
 .catch(error => {
   dispatch({ type: AUTH_FAILED });
   dispatch({ type: ERROR, payload: error.data.error.message });
 });

ドキュメントから:

要求の応答には、次の情報が含まれます。

{
  // `data` is the response that was provided by the server
  data: {},

  // `status` is the HTTP status code from the server response
  status: 200,

  // `statusText` is the HTTP status message from the server response
  statusText: 'OK',

  // `headers` the headers that the server responded with
  headers: {},

  // `config` is the config that was provided to `axios` for the request
  config: {}
}

catch(error => )は実際にはcatch(response => )です

編集:

エラーをログに記録するとそのスタックメッセージが返される理由はまだわかりません。このようにログに記録してみました。そして、実際にそれがオブジェクトであることを確認できます。

console.log('errorType', typeof error);
console.log('error', Object.assign({}, error));

EDIT2:

少し調べてみると this が印刷しようとしています。これはJavasciptエラーオブジェクトです。次に、Axiosは this のような設定、コード、応答でこのエラーを改善します。

console.log('error', error);
console.log('errorType', typeof error);
console.log('error', Object.assign({}, error));
console.log('getOwnPropertyNames', Object.getOwnPropertyNames(error));
console.log('stackProperty', Object.getOwnPropertyDescriptor(error, 'stack'));
console.log('messageProperty', Object.getOwnPropertyDescriptor(error, 'message'));
console.log('stackEnumerable', error.propertyIsEnumerable('stack'));
console.log('messageEnumerable', error.propertyIsEnumerable('message'));
35
Jeroen Wienk

getUserList() {
    return axios.get('/users')
      .then(response => response.data)
      .catch(error => {
        if (error.response) {
          console.log(error.response);
        }
      });
  }

エラーオブジェクトの応答を確認します。これには探しているオブジェクトが含まれているため、error.response.statusを実行できます

enter image description here

https://github.com/mzabriskie/axios#handling-errors

33
Steven Leggett

errorオブジェクトを処理する適切な方法を次に示します。

axios.put(this.apiBaseEndpoint + '/' + id, input)
.then((response) => {
    // Success
})
.catch((error) => {
    // Error
    if (error.response) {
        // The request was made and the server responded with a status code
        // that falls out of the range of 2xx
        // console.log(error.response.data);
        // console.log(error.response.status);
        // console.log(error.response.headers);
    } else if (error.request) {
        // The request was made but no response was received
        // `error.request` is an instance of XMLHttpRequest in the browser and an instance of
        // http.ClientRequest in node.js
        console.log(error.request);
    } else {
        // Something happened in setting up the request that triggered an Error
        console.log('Error', error.message);
    }
    console.log(error.config);
});

OriginのURL https://Gist.github.com/fgilio/230ccd514e9381fafa51608fcf13725

6
Supervision

私もこれにしばらく困惑しました。やり直しはあまりしませんが、2セントを追加することは他の人にも役立つと思いました。

上記のコードのerrorErrorタイプです。何が起こるかは、コンソールに何かを印刷しようとしているため、エラーオブジェクトで toString メソッドが呼び出されることです。これは暗黙的であり、コンソールへの書き込みの結果です。エラーオブジェクトのtoStringのコードを見ると。

Error.prototype.toString = function() {
  'use strict';

  var obj = Object(this);
  if (obj !== this) {
    throw new TypeError();
  }

  var name = this.name;
  name = (name === undefined) ? 'Error' : String(name);

  var msg = this.message;
  msg = (msg === undefined) ? '' : String(msg);

  if (name === '') {
    return msg;
  }
  if (msg === '') {
    return name;
  }

  return name + ': ' + msg;
};

上記のように、内部を使用してコンソールに出力する文字列を作成します。

素晴らしい docs がmozillaでこれにあります。

2
Ryan-Neal Mes

インラインif elseステートメントを次のように使用できます。

.catch(error => {
    dispatch({
        type: authActions.AUTH_PROCESS_ERROR,
        error: error.response ? error.response.data.code.toString() : 'Something went wrong, please try again.'
    }); 
});
0
Anton Artemev