使用 axios 处理来自异步等待语法的错误
Posted
技术标签:
【中文标题】使用 axios 处理来自异步等待语法的错误【英文标题】:Handling error from async await syntax with axios 【发布时间】:2019-03-01 21:32:19 【问题描述】:这是我的代码块:
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
;
如您所见,我正在连接到外部服务器以获取令牌。那行得通。现在,我想捕获一个错误,但这次不是“抛出新错误”,而是我想将它发送给用户,所以我想要这样的东西:
res.status(401).send('Unable to get a token');
但是因为我不在路由处理程序中,所以我不能使用“res”。那我怎样才能把它发送给用户呢?
谢谢!
【问题讨论】:
您可以在路由处理程序中等待 getToken 并在那里捕获异常。然后你就可以访问你的 res 对象了。如果您提供有关如何调用 getToken 的更多信息,我可以向您展示一个示例 【参考方案1】:优雅且带有 TypeScript。
import axios, AxiosResponse from "axios";
...
const response: void | AxiosResponse<any, any> = await axios(
headers:
Authorization: `Bearer $XYZ`,
Accept: "application/json",
,
method: "GET",
params:
...
,
url: "https://api.abcd.com/...",
).catch((error: unknown) =>
if (error instanceof Error)
console.error(
"Error with fetching ..., details: ",
error
);
);
【讨论】:
【参考方案2】:保持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
【讨论】:
【参考方案3】: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);
);
让我们从 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)
我发现这种模式行得通。假设由于 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...
【讨论】:
很好的答案,因为在这种情况下,您不需要将每个 axios 函数都包装到 try / catch 中。使用它。【参考方案4】:对于 axios 版本-0.19.0,经过数小时的异步等待后,代码工作正常。但不确定其他版本!
catch(error)
console.log(error.response.data.error)
希望有帮助!
【讨论】:
我觉得这是迄今为止这个问题的最佳答案。与其他人不同,它实际上使用触发错误提供的数据,并允许进一步处理。好一个,Akshay ? 答案应该被投票为正确答案。它允许前端检索来自后端的错误。这保存了我的项目 挣扎了一个小时,这救了我! 显示错误 TypeError: Cannot read properties of undefined (reading 'data')【参考方案5】:在我的解决方案中我使用:
try
let responseData = await axios.get(this.apiBookGetBookPages + bookId, headers);
console.log(responseData);
catch(error)
console.log(Object.keys(error), error.message);
如果某些事情失败了,我们会得到这样的错误:
[ 'config', 'request', 'response', 'isAxiosError', 'toJSON' ]
'Request failed with status code 401'
我们也可以获取状态码:
...
catch(error)
if(error.response && error.response.status == 401)
console.log('Token not valid!');
【讨论】:
【参考方案6】:你可以保持几乎相同的功能
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.')
然后从您的路由处理程序中 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);
)
默认的js异常系统可以很好的通过调用栈传递错误数据。
【讨论】:
【参考方案7】:您保留isAuthError
之类的标志,如果发生错误,则将其作为真发送,如果标志isAuthError
为真,则在主函数中抛出错误并在 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;
;
主函数
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);
)
【讨论】:
这听起来像是需要额外步骤的错误处理:)以上是关于使用 axios 处理来自异步等待语法的错误的主要内容,如果未能解决你的问题,请参考以下文章
我的 Redux 处理来自 axios 的错误应该使用不同的操作还是使用附加数据的相同操作?