处理Express异步中间件中的错误

我有一个asyncExpress中间件,因为我想在其中使用中间件await来清理我的代码。

const express = require('express');

const app = express();

app.use(async(req, res, next) => {

await authenticate(req);

next();

});

app.get('/route', async(req, res) => {

const result = await request('http://example.com');

res.end(result);

});

app.use((err, req, res, next) => {

console.error(err);

res

.status(500)

.end('error');

})

app.listen(8080);

问题在于,当它拒绝时,它不会进入我的错误中间件,但是如果我删除了async关键字,并且throw在中间件中,它将删除。

app.get('/route', (req, res, next) => {

throw new Error('Error');

res.end(result);

});

所以我得到的UnhandledPromiseRejectionWarning不是输入我的错误处理中间件,而是如何让错误冒泡并表达处理它?

回答:

问题是当它拒绝时,它不会进入我的错误中间件,但是如果我删除了async关键字并扔进了中间件中,它就会去。

express 目前不支持诺言,将来的版本可能会支持 express@5.x.x

因此,当您传递中间件函数时,express将在一个try/catch块内调用它。

Layer.prototype.handle_request = function handle(req, res, next) {

var fn = this.handle;

if (fn.length > 3) {

// not a standard request handler

return next();

}

try {

fn(req, res, next);

} catch (err) {

next(err);

}

};

问题在于,该函数try/catch不会捕获函数Promise外部的拒绝,async并且由于express没有在中间件返回的.catch函数中添加处理程序Promise,因此您会得到一个UnhandledPromiseRejectionWarning


最简单的方法是try/catch在中间件中添加,然后调用next(err)

app.get('/route', async(req, res, next) => {

try {

const result = await request('http://example.com');

res.end(result);

} catch(err) {

next(err);

}

});

但是,如果您有很多async中间件,则可能有些重复。

由于我喜欢中间件尽可能干净,并且通常让错误冒出来,所以我在async中间件周围使用包装器,next(err)如果承诺被拒绝,它将调用,到达明确的错误处理程序并避免UnhandledPromiseRejectionWarning

const asyncHandler = fn => (req, res, next) => {

return Promise

.resolve(fn(req, res, next))

.catch(next);

};

module.exports = asyncHandler;

现在您可以这样称呼它:

app.use(asyncHandler(async(req, res, next) => {

await authenticate(req);

next();

}));

app.get('/async', asyncHandler(async(req, res) => {

const result = await request('http://example.com');

res.end(result);

}));

// Any rejection will go to the error handler


还有一些可以使用的软件包

  • 异步中间件
  • 表达异步处理程序

以上是 处理Express异步中间件中的错误 的全部内容, 来源链接: utcz.com/qa/406864.html

回到顶部