Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/406.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript ExpressJS错误处理不支持';行不通_Javascript_Node.js_Express_Error Handling - Fatal编程技术网

Javascript ExpressJS错误处理不支持';行不通

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

在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错误处理功能,它也无法访问:

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)