使用 axios 处理 async await 语法中的错误

Mur*_*ami 18 node.js express

这是我的代码块:

  const getToken = async () => {
    try {
      const token = await axios.post(keys.sessionURL, {
        email: keys.verificationEmail,
        password: keys.verificationPassword,
      });
    } catch (err) {
      throw new Error('Unable to establish a login session.'); // here I'd like to send the error to the user instead
    }
  };
Run Code Online (Sandbox Code Playgroud)

如您所见,我正在连接到外部服务器以获取令牌。这有效。现在,我想捕获一个错误,但这次不是“抛出新错误”,但我想将其发送给用户,因此我想改为使用以下内容:

res.status(401).send('Unable to get a token');
Run Code Online (Sandbox Code Playgroud)

但是因为我不在路由处理程序中,所以我不能使用“res”。那么如何将其发送给用户?

谢谢!

Aks*_*eth 24

对于 axios version-0.19.0 下面的代码在与 async await 苦苦挣扎后工作了几个小时。但不确定其他版本!

catch(error){
console.log(error.response.data.error)
}
Run Code Online (Sandbox Code Playgroud)

希望有帮助!


Lev*_* K. 9

在我的解决方案中我使用:

try{
    let responseData = await axios.get(this.apiBookGetBookPages + bookId, headers);
    console.log(responseData);
}catch(error){
    console.log(Object.keys(error), error.message);
}
Run Code Online (Sandbox Code Playgroud)

如果失败,我们将收到如下错误:

[ 'config', 'request', 'response', 'isAxiosError', 'toJSON' ] 
'Request failed with status code 401'
Run Code Online (Sandbox Code Playgroud)

我们还可以获取状态码:

...
}catch(error){
    if(error.response && error.response.status == 401){
            console.log('Token not valid!');
    }
}
Run Code Online (Sandbox Code Playgroud)


小智 7

您可以保持几乎相同的功能

const getToken = async () => {
  try {
    const token = await axios.post(keys.sessionURL, {
      email: keys.verificationEmail,
      password: keys.verificationPassword,
    })
  } catch (err) {
    throw new Error('Unable to get a token.')
  }
}
Run Code Online (Sandbox Code Playgroud)

然后从你的路由处理程序只是catch最终的异常

app.get('/endpoint', async (req, res) => {
  try {
    const token = await getToken()

    // Do your stuff with the token
    // ...

  } catch (err) {
     // Error handling here
     return res.status(401).send(err.message);
  }
})
Run Code Online (Sandbox Code Playgroud)

默认的 js 异常系统可以很好地通过调用堆栈传递错误数据。


Ati*_*ain 6

你保留一个类似的标志isAuthError,如果发生错误,将其发送为true,并且在主函数中,如果标志isAuthError为true,则抛出错误并在catch中进行处理,否则执行您的操作。我在下面添加了一个示例。希望能帮助到你

const getToken = async () => {
    try {
      const token = await axios.post(keys.sessionURL, {
        email: keys.verificationEmail,
        password: keys.verificationPassword,
      });
      return {token, isAuthError: false};
    } catch (err) {
      // throw new Error('Unable to establish a login session.'); // here I'd like to send the error to the user instead
      return {err, isAuthError: true};
    }
  };
Run Code Online (Sandbox Code Playgroud)

主功能

app.post('/login', async (req, res)=>{
  try{
    // some validations

    let data = await getToken();
    if( data.isAuthError){
      throw data.err;
    }
    let token = data.token;
    //do further required operations
  }catch(err){
     //handle your error here with whatever status you need
     return res.status(500).send(err);
  }
})
Run Code Online (Sandbox Code Playgroud)


Paw*_*och 6

try/catch 不是一个好的解决方案。它的目的是捕获运行时错误,而不是来自 axios 的 HTTP 错误(如果错误由拦截器处理然后通过传递回调用者)return Promise.reject(error);

这是拦截器示例

axios.interceptors.response.use(
  response => {
    //maybe process here
    return response;
  },
  error => {
    //do some global magic with error and pass back to caller
    return Promise.reject(error);
  }
);
Run Code Online (Sandbox Code Playgroud)

让我们从不起作用的 try/catch 示例开始

for(let i=0; i<5;i++) {

    try{
       const result = async axios.get(`${/item/{i}}`);
    }
    catch(error) {
       //error undefined here, you would expect an error from pattern like axios.get(...).then(...).catch(real_http_error) 
    }
}
Run Code Online (Sandbox Code Playgroud)

我发现这种模式很有效。假设您想在循环中进行调用,以避免由于 JS 的异步特性而导致多次 http 调用。

for(let i=0; i<5;i++) {

    const result = async axios.get(`${/item/{i}}`).catch(error) {  //chain catch despite async keyword
       //now you access http error and you can do something with it
       //but calling break; or return; won't break for loop because you are in a callback
    }

    if(!result) { //due to http error
        continute; //keep looping for next call
        //or break; to stop processing after 1st error
    }
    
    //process response here, result.data...
}
Run Code Online (Sandbox Code Playgroud)


Dre*_*oon 6

保持优雅async / await

const result = await axios.post('/url', params)
    .catch((err) => {
       // deal with err, such as toggle loading state, recover click and scroll.
       this.loading = false;
       // recover the reject state before.
       return Promise.reject(err);
    });

this.data = result; // not exec when reject
Run Code Online (Sandbox Code Playgroud)