错误处理中间件并不总是有效

时间:2016-01-31 11:57:31

标签: node.js express error-handling

我正在使用Express建立一个示例网站,我点击了一些我不太了解的内容。
如果我理解正确的话,错误处理中间件应该是管道中的最后一个(s)。例如,工作正常:

var http = require('http');
var express = require('express');

var app = express();
app.set('view engine', 'jade');
app.set('views', './views');

app.use(express.static('./public'));
http.createServer(app).listen(portNumber, function() { });

app.get('/hello', function(req, res) {
    res.send('Welcome!');
});

app.use(function(err, req, res, next) {
    res.status(500).send('something broke!');
});

app.get('/error', function(req, res, next) {
    somethingNonExistent(2016);
});

但是,如果我在http.createServer调用之前注册该中间件,但是在注册了所有其他中间件之后,它将无法工作 - 我的代码未被调用:

var http = require('http');
var express = require('express');

var app = express();

app.use(express.static('./public'));

app.use(function(err, req, res, next) {
    res.status(500).send('something broke!');
});

http.createServer(app).listen(portNumber, function() { });

app.get('/hello', function(req, res) {
    res.send('Welcome!');
});

app.get('/error', function(req, res, next) {
    somethingNonExistent(2016);
});

我在这里想念什么?我的猜测是app.get调用内部使用一些中间件,它搞砸了。
我使用Express 3.2.6和Node.js 0.10.29,如果这有任何区别

2 个答案:

答案 0 :(得分:3)

定义路由/中间件时,您指定的app.controller('DescriptionController', function($scope, dataPassingService){ $scope.description = dataPassingService.get(); $scope.perigrafi = $scope.description.Description_en; var onoma = $scope.description.Name_en; alert("the description is " + perigrafi); }); 用于查看它是否与传入请求匹配。您的请求将始终路由到第一场比赛。请求可能有多个匹配,因此此处的顺序很重要。您可以通过调用path函数来点击下一个匹配的路由/中间件。

使用app.use挂载中间件而不指定路径时,每个路径都有资格访问该中间件。因此,如果它是您安装的第一件事,那么每个请求都将使用该中间件。

如果你想要一个catch all错误处理程序,你会想要相反 - 你应该在路由定义的最后安装中间件。您需要调用处理程序中的next()函数来实际访问此中间件:

next

请注意,如果当前路径不存在路由,那么您也将点击此catch中间件。

答案 1 :(得分:-1)

文档

http://expressjs.com/en/guide/error-handling.html

  

您可以在其他app.use()和之后定义错误处理中间件   路线呼叫;例如:

var bodyParser = require('body-parser');
var methodOverride = require('method-override');

app.use(bodyParser());
app.use(methodOverride());
app.use(function(err, req, res, next) {
  // logic
});

内部

为了便于理解,您可以想象管道。当您的控制器收到请求时,在Express中,它看起来像这样

try {
  fn(req, res, next); // your controller
} catch (err) {
  next(err);
}

因此,您的代码抛出错误,它会使用next调用err。基本上,它与调用next(new Error())相同。之后,表示试图在中间件管道中找到具有4个参数的下一个中间件。在您的情况下,错误处理程序在您的阴暗控制器之前声明了,因此他没有参与。

从技术上讲,控制器和中间件之间没有区别。 (可选)您可以传入控制器next参数,并将其调用以进一步传递管道。如果您没有致电next(),则表示您已完成处理请求。