Koa - 异步函数错误处理中的异步函数
Koa - Async function within Async function error handling
在我的 app.js
中,我有以下...
app.use(async (ctx, next) => {
try {
await next()
} catch (err) {
ctx.status = 400
ctx.body = `Uh-oh: ${err.message}`
console.log('Error handler:', err.message)
}
});
app.use(router());
然后在routes
我定义了...
router.post('/', retrieve);
检索逻辑的结构如下...
const retrieve = async ctx => {
Object.keys(ctx.request.files).forEach((key) => {
process(files[key]);
});
};
现在假设我在 retrieve
...
中抛出一个错误
const retrieve = async ctx => {
throw new Error(`Error!`);
Object.keys(ctx.request.files).forEach((key) => {
process(files[key]);
});
};
这将正常工作并一直冒泡到 app.js
。但是,process
函数也在使用 async
,如果我在那里抛出错误...
const retrieve = async ctx => {
Object.keys(ctx.request.files).forEach((key) => {
process(files[key]);
});
};
const process = async (file) => {
throw new Error(`Error!`);
...
我收到以下错误...
UnhandledPromiseRejectionWarning: Error: Error!
为什么我得到 UnhandledPromiseRejectionWarning
?我该如何修复它并使 process
内抛出的任何错误都冒泡到 app.js
?
由于 forEach 循环不是异步的,错误会在它执行后抛出,因此无法冒泡到 app.js。现在有两种解决方案,您可以使用 for
循环,或者映射承诺并等待所有承诺解决。根据您的问题的示例代码:
- 顺序调用
process
const retrieve = async ctx => {
const ctxKeys = Object.keys(ctx.request.files);
for(let i = 0 ; i < ctxKeys.length ;++i){
await process(files[ctxKeys[i]]);
}
};
- 异步调用
process
const retrieve = async ctx => {
await Promise.all(Object.keys(ctx.request.files).map(async (key) => {
await process(files[key]);
}));
};
在我的 app.js
中,我有以下...
app.use(async (ctx, next) => {
try {
await next()
} catch (err) {
ctx.status = 400
ctx.body = `Uh-oh: ${err.message}`
console.log('Error handler:', err.message)
}
});
app.use(router());
然后在routes
我定义了...
router.post('/', retrieve);
检索逻辑的结构如下...
const retrieve = async ctx => {
Object.keys(ctx.request.files).forEach((key) => {
process(files[key]);
});
};
现在假设我在 retrieve
...
const retrieve = async ctx => {
throw new Error(`Error!`);
Object.keys(ctx.request.files).forEach((key) => {
process(files[key]);
});
};
这将正常工作并一直冒泡到 app.js
。但是,process
函数也在使用 async
,如果我在那里抛出错误...
const retrieve = async ctx => {
Object.keys(ctx.request.files).forEach((key) => {
process(files[key]);
});
};
const process = async (file) => {
throw new Error(`Error!`);
...
我收到以下错误...
UnhandledPromiseRejectionWarning: Error: Error!
为什么我得到 UnhandledPromiseRejectionWarning
?我该如何修复它并使 process
内抛出的任何错误都冒泡到 app.js
?
由于 forEach 循环不是异步的,错误会在它执行后抛出,因此无法冒泡到 app.js。现在有两种解决方案,您可以使用 for
循环,或者映射承诺并等待所有承诺解决。根据您的问题的示例代码:
- 顺序调用
process
const retrieve = async ctx => {
const ctxKeys = Object.keys(ctx.request.files);
for(let i = 0 ; i < ctxKeys.length ;++i){
await process(files[ctxKeys[i]]);
}
};
- 异步调用
process
const retrieve = async ctx => {
await Promise.all(Object.keys(ctx.request.files).map(async (key) => {
await process(files[key]);
}));
};