Javascript ExpressJS错误处理不支持';行不通
在server.js文件的最后,我有以下代码:Javascript ExpressJS错误处理不支持';行不通,javascript,node.js,express,error-handling,Javascript,Node.js,Express,Error Handling,在server.js文件的最后,我有以下代码: app.use(logErrors); function logErrors (err: Error, req: Request, res: Response, next: NextFunction) { console.log(err); mongoDal.log(err.message, err); next(err); } 但当发生错误时,无法访问此代码 我还有Node.js错误处理功能,它也无法访问: proce
app.use(logErrors);
function logErrors (err: Error, req: Request, res: Response, next: NextFunction) {
console.log(err);
mongoDal.log(err.message, err);
next(err);
}
但当发生错误时,无法访问此代码
我还有Node.js错误处理功能,它也无法访问:
process.on('uncaughtException', function (err: Error) {
try {
console.log(err);
mongoDal.log(err.message, err);
} catch (err) {
}
});
这是产生错误的代码:
app.get('/test_feature', function (req: Request, res: Response) {
makeError();
res.send("Done");
});
function makeError(){
throw new Error("asdasdad");
}
顺便说一句,这个错误确实会被写入控制台(但不是由我的一个函数),并且应用程序不会崩溃
我想做的是一个通用的解决方案,它将在一个地方捕获所有未处理的异常
我做错了什么?我认为问题出在路由定义上 正如你所说,你正在使用这个
app.get('/test_feature', function (req, res) {
throw new Error("asdasdad");
res.send("Done");
});
尝试使用以下方法:
app.get('/test_feature', function (req, res, next) {
next(new Error("asdasdad"));
});
然后将res.send放在错误处理程序上
为什么?
我认为在函数中抛出错误会停止请求链。。。所以它并没有到达最后,然后是你的错误处理程序。
如果你以第二种方式写作。。。您将错误向前移动。。。然后到达处理程序…下面是处理3种类型错误的简短工作示例: 1) 传递给
next()
处理程序,
2) 将ed扔进路线处理程序,
3) 从路由处理程序调用的某个函数的回调中出现未处理的错误
(1) 和(2)使用自定义错误中间件处理程序(A)捕获,(3)由uncaughtException
处理程序(B)捕获
Express有自己的错误处理程序,如果它使用next()
调用链获取控件(即,如果没有自定义错误处理程序,或者如果它使用next(err,req,res,next)
进一步传递控件,则会输出错误。这就是为什么即使您的处理程序不是触发器,您仍然会在控制台中收到错误消息
如果您尝试运行案例(1)和(2)的示例,您将看到两次错误输出-通过自定义处理程序(A)和默认的快速错误处理程序
'use strict';
var express = require('express');
var app = express();
var server = app.listen(8080, function() {
console.log('* Server listening at ' + server.address().address + ':' + server.address().port);
});
// Example 1: Pass error in route handler to next() handler
app.use('/1', function(req, res, next) {
console.log('* route 1');
next(new Error('* route 1 error'));
});
// Example 2: throw the error in route handler
app.use('/2', function(req, res, next) {
console.log('* route 2');
throw new Error('route 2 error');
});
// Example 3: unhandled error inside some callback function
app.use('/3', function(req, res, next) {
console.log('* route 3');
setTimeout(function(){
throw new Error('route 3 error');
}, 500);
});
// Error handler A: Express Error middleware
app.use(function(err, req, res, next) {
console.log('**************************');
console.log('* [Error middleware]: err:', err);
console.log('**************************');
next(err);
});
// Error handler B: Node's uncaughtException handler
process.on('uncaughtException', function (err) {
console.log('**************************');
console.log('* [process.on(uncaughtException)]: err:', err);
console.log('**************************');
});
节点版本:v7.2.0
典型的错误是将错误处理程序放在路由定义之前,但根据您的描述,情况并非如此
为了找出问题所在,您可以尝试将自己的代码缩减到与我的代码相同的大小,我认为,问题将变得显而易见
更新 此外,如果我尝试运行您提供的代码(只做了一些小的修改),它对我来说是有效的:
'use strict';
var express = require('express');
var app = express();
var server = app.listen(8080, function() {
console.log('* Server listening at ' + server.address().address + ':' + server.address().port);
});
//process.on('uncaughtException', function (err: Error) {
process.on('uncaughtException', function (err) {
try {
console.log('*** uncaughtException:', err);
//mongoDal.log(err.message, err);
} catch (err) {
}
});
//app.get('/test_feature', function (req: Request, res: Response) {
app.get('/test_feature', function (req, res) {
makeError();
res.send("Done");
});
function makeError(){
throw new Error("asdasdad");
}
app.use(logErrors);
//function logErrors (err: Error, req: Request, res: Response, next: NextFunction) {
function logErrors (err, req, res, next) {
console.log('*** logErrors:', err);
//mongoDal.log(err.message, err);
next(err);
}
结果是(堆栈跟踪被截断):
您可能会在开始时看到
logErrors
处理程序的输出,然后是default Express error处理程序的输出。如果希望运行全局uncaughtException
,则需要在无人捕捉的位置抛出错误,如下所示:
'use strict';
var express = require('express');
var app = express();
var server = app.listen(8080, function() {
console.log('* Server listening at ' + server.address().address + ':' + server.address().port);
});
// Example 1: Pass error in route handler to next() handler
app.use('/1', function(req, res, next) {
console.log('* route 1');
next(new Error('* route 1 error'));
});
// Example 2: throw the error in route handler
app.use('/2', function(req, res, next) {
console.log('* route 2');
throw new Error('route 2 error');
});
// Example 3: unhandled error inside some callback function
app.use('/3', function(req, res, next) {
console.log('* route 3');
setTimeout(function(){
throw new Error('route 3 error');
}, 500);
});
// Error handler A: Express Error middleware
app.use(function(err, req, res, next) {
console.log('**************************');
console.log('* [Error middleware]: err:', err);
console.log('**************************');
next(err);
});
// Error handler B: Node's uncaughtException handler
process.on('uncaughtException', function (err) {
console.log('**************************');
console.log('* [process.on(uncaughtException)]: err:', err);
console.log('**************************');
});
app.get('/test_feature', function (req: Request, res: Response) {
setTimeout(function () { throw new Error('oops'); }, 1000);
res.send("Done");
});
express捕获处理程序内部的同步抛出,捕获时根本不会发生未捕获异常
根据,错误处理中间件是在路由和其他中间件之后定义的
app.get('/test_feature', function (req: Request, res: Response) {
makeError();
res.send("Done");
});
app.use(logErrors)
如果获得错误的顺序,则在抛出某个对象时将不会调用错误处理程序。注意:错误处理程序中间件必须有4个参数:error、req、res、next。否则你的处理者不会开火
我一直在努力解决这个问题,直到我发现了这个问题。您如何定义yout请求??app.get(req,res)???@LucasKatayama yesExpress已经有一个默认的错误处理程序,它可能是记录错误的处理程序。我的猜测是,您正在安装错误处理程序,但它不是最后一个中间件,但如果不知道您的应用程序是如何构造的(是
server.js
app入口点,还是通过其他文件启动应用程序?@robertklep我可以这样启动我的应用程序:“node server.js”,这是第一个执行的文件。@Alon-hmm,听起来不错。我相当肯定,由于某些原因,您的错误处理程序没有正确注册,默认的错误处理程序将生效。你可以试着在调试模式下运行你的应用程序,看看这是否能说明发生了什么:debug=*node server.js
我简化了我的代码。我实际上从我调用的函数中得到了一个错误。我可以使用try/catch块捕获它,但我不想在每个app.get函数中添加try/catch块。我想要一个通用的解决方案,它可以在一个地方捕获所有未处理的异常。我只是没能找到我做错了什么。您发送的示例在我看来就像我的代码。我一定错过了什么。在路由中抛出会通过express自动调用next(err)。另一个建议是,您前面有另一个错误处理程序,它会打印错误消息,但不会使用next(err)