处理Express异步中间件中的错误
我有一个async
Express中间件,因为我想在其中使用中间件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