我正在开发 express 应用程序,在指定所有路由和中间件后,我在 server.js 的末尾有这个:
// Log errors
app.use(function (err, req, res, next) {
logger.error(err.stack);
if(process.env.NODE_ENV === 'production')
return res.status(500).send('Something broke!');
next(err);
});
// Start server
app.listen(port, () => {
logger.info('Server is up on port ' + port);
});
Run Code Online (Sandbox Code Playgroud)
这样做的目的是捕获生产中的所有错误并避免将敏感数据泄露给客户端。
我的其中一个控制器中有此代码:
const createHTTPError = require('http-errors')
async function(req, res, next) {
try {
invoice = await Invoice.create({
// data
});
}catch (e) {
if(e instanceof Sequelize.ValidationError){
logger.error(e);
return next(createHTTPError(400, 'Validation did not pass: ' + e.message));
}
}
}
Run Code Online (Sandbox Code Playgroud)
问题是,当next()用http-errorsobject调用时,它冒泡到我的 catch-all 错误处理程序,但信息丢失了,其中 err 对象是一个Error带有这些参数的简单实例:
message = "Validation did not pass: notNull Violation: invoice.clientEmail cannot be null"
name = "BadRequestError"
stack = "BadRequestError: Validation did not pass: notNull Violation: invoice.clientEmail cannot be null\n at module.exports (/home/XXXX/create-new-invoice.js:109:33)"
Run Code Online (Sandbox Code Playgroud)
错误代码编号丢失。错误对象类型丢失(好吧,转换为名称中的字符串)。
我该怎么办?如果我删除我的全部内容,我就有可能泄露一些敏感信息。谢谢
所以我最终得到了这段代码:
const HTTPErrors = require('http-errors');
const HTTPStatuses = require('statuses');
// ... set up express, middlewares, routes...
// Log errors
app.use(function (err, req, res, next) {
let messageToSend;
if(err instanceof HTTPErrors.HttpError){
// handle http err
messageToSend = {message: err.message};
if(process.env.NODE_ENV === 'development')
messageToSend.stack = err.stack;
messageToSend.status = err.statusCode;
}else{
// log other than HTTP errors (these are created by me manually, so I can log them when thrown)
logger.error(err.stack);
}
if(process.env.NODE_ENV === 'production' && !messageToSend){
messageToSend = {message: 'Something broke', status: 500};
}
if(messageToSend) {
let statusCode = parseInt(messageToSend.status,10);
let statusName = HTTPStatuses[statusCode];
res.status(statusCode);
// respond with html page
if (req.accepts('html')) {
res.send('<html><head><title>'+statusCode+' '+statusName+'</title></head><body><h1>'+statusCode+' '+statusName+'</h1>'+messageToSend.message+'<br/><br/>'+(messageToSend.stack ? messageToSend.stack : '')+'</body></html>');
return;
}
// respond with json
if (req.accepts('json')) {
let responseObject = { error: statusName, code: statusCode, message: messageToSend.message };
if(messageToSend.stack)
responseObject.stack = messageToSend.stack;
res.send(responseObject);
return;
}
// default to plain-text. send()
res.type('txt').send(statusName+' '+messageToSend.message);
return;
}
// if this is not HTTP error and we are not in production, let express handle it the default way
next(err);
});
Run Code Online (Sandbox Code Playgroud)
这个解决方案:
http-errors模块中的 HTTP 错误(对于开发使用堆栈跟踪,对于生产不使用堆栈跟踪)我还在 404 catchall 中利用了这个新的 catchall 函数:
// DEFAULT CATCH
app.use(function(req, res, next){
next(HTTPErrors(404));
});
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3196 次 |
| 最近记录: |