我正在使用Express,并且想使用内置的中间件来处理错误。
我正以这种方式使用它-
app.use((err,req,res,next)=> {
console.log('error');
)};
现在,仅当我在路由器中使用next(error)
(其中error
是Error
类型的对象)时,此中间件才可用。
另一方面,如果我只是在路由器中throw new Error()
,则不会调用中间件。
有什么办法可以省略next()
?
这样,如果我的路由器中抛出任何错误,它将由中间件处理?
答案 0 :(得分:0)
如果引发是同步的,则可以发明自己的请求处理程序包装器,该包装器将捕获所有异常并将其转换为对next()
的调用:
app.get2 = function(path, fn) {
app.get(path, function(req, res, next) {
try {
fn(req, res, next);
} catch(err) {
next(err);
}
});
};
并且,用法示例:
app.get2("/test", function(req, res, next) {
throw new Error("testing..."); // will end up in next()
});
然后,如果您的fn
函数同步引发,那么它将被您的get2()
包装器捕获,并会自动为您调用next(err)
。
如果异步抛出,则无法正常工作。没有用于异步引发的通用包装器,因为引发异步回调的引发不会投给您的代码-它们会针对您正在使用的任何异步操作返回到异步基础结构中,并且只有它们可以捕获它。如果您仅将诺言用于异步操作,则诺言基础结构将自动捕获您的抛出并将其转变为拒绝的诺言,您可以对返回和拒绝的诺言执行与上述类似的操作。 Koa框架(Express的派生)已经做了类似的事情,我认为Express 5将具有类似的功能。
答案 1 :(得分:0)
如果您可以使用async/await
随附的Node.js> = 8,则可以在路由上使用以下包装函数:
const wrap = fn => {
return async function(req, res, next) {
let e = null;
try {
await fn(req, res, next);
} catch (err) {
e = err;
next(err);
}
if (!e) {
next();
}
};
};
app.get(
"/path",
wrap(async (req, res) => {
// use sync style code here which can throw
})
);