我正在使用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,如果这有任何区别
答案 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()
,则表示您已完成处理请求。