从Await调用中捕获错误后,如何停止Express.js中的执行



我发现很多帖子几乎回答了这个问题,但没有什么对我有效。

我有一个异步功能:

const doStuff = async (data)=>{
if(data == "a bug")
throw(new Error('Error! Bug found'));
return "not a bug";
}

我调用路由处理程序上的函数:

app.get('/doStuffRoute', async (req, res, next)=>{
const result = await doStuff("a bug")
.catch((err)=>{return next(err);});
console.log("This shouldn't execute!");
}

我的自定义错误中间件可以很好地处理错误,打印出错误等。但我仍然看到This shouldn't execute!也在打印!

从我所有的研究和阅读来看,await X.catch(error)应该try{ await X } catch {error}相同。如果可能的话,我真的更喜欢.catch();。有几十个教程显示了这一点,甚至有一些stackoverflow帖子明确说明了这一情况。然而,我偶尔也会发现一个帖子隐晦地说";不要将wait与.catch((一起使用"没有其他解释或细节,所以我不知道该怎么想。

我能找到的唯一提示是在next(err)调用应该足以停止执行之前添加return,但如果return next(err);.catch()块内,它似乎实际上不起作用。

发生了什么事?我的消息来源在撒谎吗?我是不是误解了一些基本的概念?我感谢任何帮助我走上正轨。

作为一个额外的问题,为什么这么多人建议使用包装器函数a-la-express异步处理程序?为什么这与直接调用异步函数并处理它有任何不同的行为?

被拒绝的promise不会停止进一步的Javascript执行,因此.catch()处理程序不会停止任何操作。事实上,由于async函数是异步的,所以console.log()甚至会在.catch()处理程序执行之前执行。因此,您需要设计尊重promise状态的代码流。

我建议这样做:

app.get('/doStuffRoute', async (req, res, next) => {
try {
const result = await doStuff("a bug");
console.log("doStuff() resolved");
} catch(err) {
console.log("doStuff() rejected");
next(err);
}
}

通过这种方式,您已经清楚地描绘了已解析承诺和已拒绝承诺的两个代码路径,并且可以将代码放置在适当的代码路径中。

进行时

const result = await doStuff("a bug").catch((err)=>{return next(err);});
console.log(result) // you will see undefined 

因为当您传递参数err并将其存储在结果变量中时,它试图评估下一个方法,类似地,如果您这样做,

const add = (err)=>{
if(err instanceof Error){ return 2}
return 3
}
const result = await doStuff("a bug").catch((err)=>{return add(err);});
console.log(result) // you will see 2

在回答您的问题时,当回调函数中有return语句时,只有回调函数的执行结束。这意味着主父函数将继续执行。

const result = await doStuff("a bug").catch((err)=>{return err;});
console.log(result) // now result is an Error object
if(result instanceof Error){
next(result) //if an error handler is defined call that or call default express error handler
return //stop execution of route callback
} 
console.log("will NOT execute if there is an error")

但我想补充一点,有更好的方法来处理异步express路由的错误,本文对此进行了详细解释。

https://zellwk.com/blog/async-await-express/

最新更新