我正在开发快速应用程序,在指定了所有路由和中间件之后,我在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);
});
这样做的目的是捕获生产中的所有错误,并避免将敏感数据泄露给客户端。
我的一个控制器中有以下代码:
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));
}
}
}
问题是,当用next()
对象调用http-errors
时,它冒泡到我的全部错误处理程序,但是信息丢失了,并且其中的err对象是一个简单的{{1 }}具有以下参数的实例:
Error
错误代码号丢失。错误对象类型丢失了(好吧,名称转换为字符串)。
我该怎么办?如果删除所有内容,则可能会泄露一些敏感信息。谢谢
答案 0 :(得分:0)
所以我最终得到了这段代码:
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);
});
此解决方案:
http-errors
模块的HTTP错误(带有用于开发而未用于生产的堆栈跟踪)我还在404 catchall中利用了这个新的catchall函数:
// DEFAULT CATCH
app.use(function(req, res, next){
next(HTTPErrors(404));
});