javascript - ExpressJS 错误处理不起作用

标签 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 的错误处理函数,也没有达到:

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");
}

顺便说一句,错误确实写入了控制台(但不是通过我的功能),并且应用程序没有崩溃。

我想做的是一个通用的解决方案,它将在一个地方捕获所有未处理的异常。

我做错了什么?

最佳答案

下面是处理 3 种类型错误的简短工作示例: 1) 传递给 next()处理程序, 2) throw-ed 内部路由处理程序, 3) 从路由处理程序调用的某些函数的回调内部未处理的错误。

(1) 和 (2) 使用自定义错误中间件处理程序捕获 (A) 和 (3) 由 uncaughtException 捕获处理程序(B)。

Express 有自己的错误处理程序,如果它使用 next() 链获取控制权,它会输出错误。调用(即,如果没有自定义错误处理程序,或者如果它使用 next(err, req, res, next) 进一步传递控制)。这就是为什么即使您的处理程序不是触发器,您仍然会在控制台中收到错误消息。

如果您尝试针对情况 (1) 和 (2) 运行示例,您将看到两次错误输出 - 通过自定义处理程序 (A) 和默认的 Express 错误处理程序。

'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('**************************');
});

Node 版本: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);
}

结果是(堆栈跟踪被 chop ):

* Server listening at :::8080
*** logErrors: Error: asdasdad
    at makeError (/home/alykoshin/sync/al-projects/dev/nmotw/400-express-error-handling/main-stackoverflow.js:32:9)
...........
Error: asdasdad
    at makeError (/home/alykoshin/sync/al-projects/dev/nmotw/400-express-error-handling/main-stackoverflow.js:32:9)
...........

您可能会在开头看到 logErrors 的输出处理程序,然后是默认 Express 错误处理程序的输出。

关于javascript - ExpressJS 错误处理不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40772614/

相关文章:

javascript - 如何将第三方包导入Meteor?

javascript - Require 在 NodeJS 应用程序中无法识别

node.js - Passport express /注册 500 未知错误

javascript - react Js : Pass props to React Router's Link component Error

电话号码中的Javascript破折号

javascript - Highcharts:每次点击按钮动态更新图表

json - 为什么 Angular Universal Server Side Rendering 在部署到 Firebase Hosting 后会出错?

javascript - 使用_this引用父类方法

javascript - 如何在 node-js 中从 UUID 返回字符串

javascript - 将一个对象的值和属性合并到另一个对象中