如何优雅地处理 express 中的 promise rejection
How to gracefully handle promise rejection in express
我有以下快递控制器
class ThingsController {
static async index(req, res, next) {
try {
const things = await Thing.all();
res.json(things);
} catch(err) {
next(err);
}
}
}
和路由器
router.route('/things').get(ThingsController.index)
在我的应用程序中,我计划有几个使用 promises 来呈现结果的控制器
我不想每次都重复try/catch块
我的第一个解决方案是将此逻辑提取到句柄承诺拒绝函数中:
const handlePromiseRejection = (handler) =>
async (req, res, next) => {
try{
await handler(req, res, next);
} catch(err) {
next(err);
};
};
现在我们可以从 ThingsController.index 中删除 try/catch 块,需要将路由器更改为:
router.route('/things')
.get(handlePromiseRejection(ThingsController.index))
但是在每条路线上添加 handlePromiseRejection
可能是一项乏味的任务,我希望有更聪明的解决方案。
你有什么想法吗?
所以,如果你真的想在每条路线上处理,这就是你处理承诺拒绝的方式。
这也是它的单行 ES6 版本。
代码
const handlePromiseRejection = (handler) => (req, res, next) => handler(req, res, next).catch(next)
尽管如您所问,最简单的方法是在您的 index.js 或 app.js
上使用过程中收听 unhandledRejection
process.on("unhandledRejection", (error, promise) => {
console.log("Unhandled Rejection at:", promise, "reason:", reason);
// Application specific logging, throwing an error, or other logic here
});
来自Node.js
在路由中使用 async/await
处理错误的正常方法是捕获错误并将其传递给 catch all
错误处理程序:
app.use(async (req, res) => {
try {
const user = await someAction();
} catch (err) {
// pass to error handler
next(err)
}
});
app.use((err, req, res, next) => {
// handle error here
console.error(err);
});
使用 express-async-errors
包,您可以简单地 throw
(或者不用担心 error
从某些函数中抛出)。来自文档:Instead of patching all methods on an express Router, it wraps the Layer#handle property in one place, leaving all the rest of the express guts intact.
用法很简单:
require('express-async-errors'); // just require!
app.use(async (req, res) => {
const user = await User.findByToken(req.get('authorization')); // could possibly throw error, implicitly does catch and next(err) for you
// throw some error and let it be implicitly handled !!
if (!user) throw Error("access denied");
});
app.use((err, req, res, next) => {
// handle error
console.error(err);
});
我有以下快递控制器
class ThingsController {
static async index(req, res, next) {
try {
const things = await Thing.all();
res.json(things);
} catch(err) {
next(err);
}
}
}
和路由器
router.route('/things').get(ThingsController.index)
在我的应用程序中,我计划有几个使用 promises 来呈现结果的控制器
我不想每次都重复try/catch块
我的第一个解决方案是将此逻辑提取到句柄承诺拒绝函数中:
const handlePromiseRejection = (handler) =>
async (req, res, next) => {
try{
await handler(req, res, next);
} catch(err) {
next(err);
};
};
现在我们可以从 ThingsController.index 中删除 try/catch 块,需要将路由器更改为:
router.route('/things')
.get(handlePromiseRejection(ThingsController.index))
但是在每条路线上添加 handlePromiseRejection
可能是一项乏味的任务,我希望有更聪明的解决方案。
你有什么想法吗?
所以,如果你真的想在每条路线上处理,这就是你处理承诺拒绝的方式。
这也是它的单行 ES6 版本。
代码
const handlePromiseRejection = (handler) => (req, res, next) => handler(req, res, next).catch(next)
尽管如您所问,最简单的方法是在您的 index.js 或 app.js
上使用过程中收听unhandledRejection
process.on("unhandledRejection", (error, promise) => {
console.log("Unhandled Rejection at:", promise, "reason:", reason);
// Application specific logging, throwing an error, or other logic here
});
来自Node.js
在路由中使用 async/await
处理错误的正常方法是捕获错误并将其传递给 catch all
错误处理程序:
app.use(async (req, res) => {
try {
const user = await someAction();
} catch (err) {
// pass to error handler
next(err)
}
});
app.use((err, req, res, next) => {
// handle error here
console.error(err);
});
使用 express-async-errors
包,您可以简单地 throw
(或者不用担心 error
从某些函数中抛出)。来自文档:Instead of patching all methods on an express Router, it wraps the Layer#handle property in one place, leaving all the rest of the express guts intact.
用法很简单:
require('express-async-errors'); // just require!
app.use(async (req, res) => {
const user = await User.findByToken(req.get('authorization')); // could possibly throw error, implicitly does catch and next(err) for you
// throw some error and let it be implicitly handled !!
if (!user) throw Error("access denied");
});
app.use((err, req, res, next) => {
// handle error
console.error(err);
});