Dan*_*iel 51 node.js express es6-promise
我在Express应用程序中运行了很多基于ES6 promise的代码.如果有一个从未被捕获的错误,我正在使用以下代码来处理它:
process.on('unhandledRejection', function(reason, p) {
console.log("Unhandled Rejection:", reason.stack);
process.exit(1);
});
Run Code Online (Sandbox Code Playgroud)
这适用于调试目的.
但是在生产中我想触发500错误处理程序,向用户显示标准的"出错了"页面.我有这个捕获当前适用于其他异常的所有错误处理程序:
app.use(function(error, req, res, next) {
res.status(500);
res.render('500');
});
Run Code Online (Sandbox Code Playgroud)
将unhandledRejection放在中间件中不起作用,因为它的异步和offen导致a Error: Can't render headers after they are sent to the client.
我将如何渲染500页unhandledRejection?
Jar*_*tra 27
将unhandledRejection放在中间件中...通常会导致a
Error: Can't render headers after they are sent to the client.
对您的错误处理程序稍作更改:
// production error handler
const HTTP_SERVER_ERROR = 500;
app.use(function(err, req, res, next) {
if (res.headersSent) {
return next(err);
}
return res.status(err.status || HTTP_SERVER_ERROR).render('500');
});
Run Code Online (Sandbox Code Playgroud)
Express附带了一个内置的错误处理程序,它可以处理应用程序中可能遇到的任何错误.此缺省错误处理中间件添加在中间件堆栈的末尾.
如果将错误传递给next()并且您没有在错误处理程序中处理它,它将由内置错误处理程序处理 - 错误将通过堆栈跟踪写入客户端.堆栈跟踪不包含在生产环境中.
将环境变量NODE_ENV设置为"production",以在生产模式下运行应用程序.
如果在开始编写响应后调用next()并出现错误,例如,如果在将响应流式传输到客户端时遇到错误,则Express的默认错误处理程序将关闭连接并使请求被视为失败.
因此,当您添加自定义错误处理程序时,您将希望在已将标头发送到客户端时委派给express中的默认错误处理机制.
小智 21
我使用next参数作为catch回调(aka errback)来转发任何未处理的拒绝来表达错误处理程序:
app.get('/foo', function (req, res, next) {
somePromise
.then(function (result) {
res.send(result);
})
.catch(next); // <----- NOTICE!
}
Run Code Online (Sandbox Code Playgroud)
或更短的形式:
app.get('/foo', function (req, res, next) {
somePromise
.then(function (result) {
res.send(result);
}, next); // <----- NOTICE!
}
Run Code Online (Sandbox Code Playgroud)
然后我们可以err在快速错误处理程序中使用参数发出有意义的错误响应
例如,
app.use(function (err, req, res, /*unused*/ next) {
// bookshelf.js model not found error
if (err.name === 'CustomError' && err.message === 'EmptyResponse') {
return res.status(404).send('Not Found');
}
// ... more error cases...
return res.status(500).send('Unknown Error');
});
Run Code Online (Sandbox Code Playgroud)
恕我直言,全球unhandledRejection事件不是最终的答案.
例如,这容易发生内存泄漏:
app.use(function (req, res, next) {
process.on('unhandledRejection', function(reason, p) {
console.log("Unhandled Rejection:", reason.stack);
res.status(500).send('Unknown Error');
//or next(reason);
});
});
Run Code Online (Sandbox Code Playgroud)
但这TOO重:
app.use(function (req, res, next) {
var l = process.once('unhandledRejection', function(reason, p) {
console.log("Unhandled Rejection:", reason.stack);
res.status(500).send('Unknown Error');
//next(reason);
});
next();
process.removeEventLister('unhandledRejection', l);
});
Run Code Online (Sandbox Code Playgroud)
恕我直言,expressjs需要更好的支持Promise.
我一直在寻找一种干净的方法来处理它,Express 5 现在通过设计处理异步承诺:
从 Express 5 开始,返回 Promise 的路由处理程序和中间件将在拒绝或抛出错误时自动调用 next(value)。例如
https://expressjs.com/en/guide/error-handling.html
默认情况下,如果您的请求是async抛出错误的函数,express 不会将错误传递给中间件。相反process.on('unhandledRejection', callback)被调用,请求将被阻塞。
创建库express-async-errors来解决这些错误。
您需要添加require('express-async-errors');到您的代码中,库将确保您的所有函数都进入处理程序。即使这是一个未经处理的拒绝。
| 归档时间: |
|
| 查看次数: |
14673 次 |
| 最近记录: |