Axios处理错误

时间:2018-04-22 15:45:24

标签: javascript promise axios

我正试图通过Axios更好地理解javascript承诺。我假装的是处理Request.js中的所有错误,只从任何地方调用请求函数而不必使用catch()

在此示例中,对请求的响应将为400,并在JSON中显示错误消息。

这是我得到的错误:

Uncaught (in promise) Error: Request failed with status code 400

我找到的唯一解决方案是在Somewhere.js中添加.catch(() => {}),但我正在努力避免这样做。有可能吗?

以下是代码:

  

Request.js

export function request(method, uri, body, headers) {
  let config = {
    method: method.toLowerCase(),
    url: uri,
    baseURL: API_URL,
    headers: { 'Authorization': 'Bearer ' + getToken() },
    validateStatus: function (status) {
      return status >= 200 && status < 400
    }
  }

  ...

  return axios(config).then(
    function (response) {
      return response.data
    }
  ).catch(
    function (error) {
      console.log('Show error notification!')
      return Promise.reject(error)
    }
  )
}
  

Somewhere.js

export default class Somewhere extends React.Component {

  ...

  callSomeRequest() {
    request('DELETE', '/some/request').then(
      () => {
        console.log('Request successful!')
      }
    )
  }

  ...

}

7 个答案:

答案 0 :(得分:25)

如果要访问整个错误正文,请按照以下所示进行操作:

 async function login(reqBody) {
  try {
    let res = await Axios({
      method: 'post',
      url: 'https://myApi.com/path/to/endpoint',
      data: reqBody
    });

    let data = res.data;
    return data;
  } catch (error) {
    console.log(error.response); // this is the main part. Use the response property from the error object

    return error.response;
  }

}

答案 1 :(得分:14)

您可以像这样去: error.response.data
就我而言,我从后端获得了 error 属性。因此,我使用了 error.response.data.error

我的代码:

axios
     .get(`${API_BASE_URL}/students`)
     .then(response => {
        return response.data
      })
     .then(data => {
        console.log(data)
     .catch(error => {
       console.log(error.response.data.error)
      })

答案 2 :(得分:7)

实际上,到目前为止,axios无法实现。仅在2xx范围内的状态代码可以捕获在.then()中。

常规方法是在catch()块中捕获错误,如下所示:

axios.get('/api/xyz/abcd')
  .catch(function (error) {
    if (error.response) {
      // Request made and server responded
      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
      console.log(error.request);
    } else {
      // Something happened in setting up the request that triggered an Error
      console.log('Error', error.message);
    }

  });

另一种方法是拦截请求或响应,然后再由它们处理或捕获。

axios.interceptors.request.use(function (config) {
    // Do something before request is sent
    return config;
  }, function (error) {
    // Do something with request error
    return Promise.reject(error);
  });

// Add a response interceptor
axios.interceptors.response.use(function (response) {
    // Do something with response data
    return response;
  }, function (error) {
    // Do something with response error
    return Promise.reject(error);
  });

答案 3 :(得分:4)

我尝试使用 try{}catch{} 方法,但它对我不起作用。但是,当我切换到使用 .then(...).catch(...) 时,AxiosError 被正确捕获,我可以使用它。当我在放置断点时尝试前者时,它不允许我看到 AxiosError,而是告诉我捕获的错误未定义,这也是最终在 UI 中显示的内容。

不知道为什么会发生这种情况,我觉得这很微不足道。无论哪种方式,我都建议使用上面提到的传统 .then(...).catch(...) 方法,以避免向用户抛出未定义的错误。

答案 4 :(得分:1)

从任何地方调用请求函数,而不必使用catch()。

首先,虽然在一个地方处理大多数错误是一个好主意,但处理请求并不是那么容易。某些错误(例如“用户名已使用”或“无效的电子邮件”等400个验证错误)应该继续传递。

所以我们现在使用基于Promise的函数:

const baseRequest = async (method: string, url: string, data: ?{}) =>
  new Promise<{ data: any }>((resolve, reject) => {
    const requestConfig: any = {
      method,
      data,
      timeout: 10000,
      url,
      headers: {},
    };

    try {
      const response = await axios(requestConfig);
      // Request Succeeded!
      resolve(response);
    } catch (error) {
      // Request Failed!

      if (error.response) {
        // Request made and server responded
        reject(response);
      } else if (error.request) {
        // The request was made but no response was received
        reject(response);
      } else {
        // Something happened in setting up the request that triggered an Error
        reject(response);
      }
    }
  };

然后您可以使用类似的请求

try {
  response = await baseRequest('GET', 'https://myApi.com/path/to/endpoint')
} catch (error) {
  // either handle errors or don't
}

答案 5 :(得分:1)

如果我理解正确,您希望请求函数的 then 仅在请求成功时才被调用,并且您希望忽略错误。为此,您可以创建一个新的承诺,在 axios 请求成功时解决它,并且在失败时永远不会拒绝它。

更新后的代码如下所示:

export function request(method, uri, body, headers) {
  let config = {
    method: method.toLowerCase(),
    url: uri,
    baseURL: API_URL,
    headers: { 'Authorization': 'Bearer ' + getToken() },
    validateStatus: function (status) {
      return status >= 200 && status < 400
    }
  }


  return new Promise(function(resolve, reject) {
    axios(config).then(
      function (response) {
        resolve(response.data)
      }
    ).catch(
      function (error) {
        console.log('Show error notification!')
      }
    )
  });

}

答案 6 :(得分:0)

如果您想使用异步等待,请尝试

export const post = async ( link,data ) => {
const option = {
    method: 'post',
    url: `${URL}${link}`,
    validateStatus: function (status) {
        return status >= 200 && status < 300; // default
      },
    data
};

try {
    const response = await axios(option);
} catch (error) {
    const { response } = error;
    const { request, ...errorObject } = response; // take everything but 'request'
    console.log(response);

}
 };