我查看了Express的文档,描述错误处理的部分对我来说是完全不透明的。
我认为他们所指的app
是一个实例createServer()
,对吗?但是,我不知道如何在处理请求期间出现异常时阻止node.js破坏应用程序进程。
我真的不需要任何花哨的东西;只要有异常,我只想返回状态500,加上一个空的响应。节点进程不能仅仅因为某个地方有一个未察觉的异常而终止。
有没有一个简单的例子说明如何做到这一点?
var express = require('express');
var http = require('http');
var app = express.createServer();
app.get('/', function(req, res){
console.log("debug", "calling")
var options = {
host: 'www.google.com',
port: 80,
path: "/"
};
http.get(options, function(response) {
response.on("data", function(chunk) {
console.log("data: " + chunk);
chunk.call(); // no such method; throws here
});
}).on('error', function(e) {
console.log("error connecting" + e.message);
});
});
app.configure(function(){
app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));
});
app.listen(3000);
使整个应用程序崩溃,产生回溯
mypath/tst.js:16
chunk.call(); // no such method; throws here
^ TypeError: Object ... has no method 'call'
at IncomingMessage.<anonymous> (/Library/WebServer/Documents/discovery/tst.js:16:18)
at IncomingMessage.emit (events.js:67:17)
at HTTPParser.onBody (http.js:115:23)
at Socket.ondata (http.js:1150:24)
at TCP.onread (net.js:374:27)
发布于 2013-04-09 21:48:44
如果您确实希望捕获所有异常并提供一些处理,而不是退出Node.js进程,则需要处理Node的uncaughtException事件。
如果您仔细想想,这是一个Node问题,而不是Express问题,因为如果您从任意代码中抛出一个异常,则没有任何保证Express能够或永远看到它,也无法保证它能够被捕获。(为什么?异常与异步事件驱动的回调代码(即Node样式)之间的交互不太好。异常在调用堆栈中遍历,以找到抛出异常时范围内的catch()
块。如果myFunction
将一些工作交付给在某些事件发生时运行的回调函数,那么返回到事件循环,然后当调用该回调函数时,直接从主事件循环调用它,并且myFunction
不再在调用堆栈中;如果这个回调函数抛出异常,即使myFunction
有try/catch块,它也不会捕获异常。)
这实际上意味着,如果您抛出一个异常而不亲自捕获它,并且在一个由Express直接调用的函数中这样做,Express可以捕获异常并调用您安装的错误处理程序,前提是您已经配置了一些像app.use(express.errorHandler())
这样的错误处理中间件。但是,如果在响应异步事件的函数中抛出相同的异常,Express将无法捕获它。(捕获它的唯一方法是侦听全局Node uncaughtException
事件,这将是个坏主意,首先因为这是全局的,您可能需要将它用于其他事情,其次,因为Express将不知道什么请求与异常相关联。)
下面是一个例子。我将这个路由处理代码片段添加到一个现有的Express应用程序中:
app.get('/fail/sync', function(req, res) {
throw new Error('whoops');
});
app.get('/fail/async', function(req, res) {
process.nextTick(function() {
throw new Error('whoops');
});
});
现在,如果我在浏览器中访问http://localhost:3000/fail/sync
,浏览器将转储一个调用堆栈(显示express.errorHandler在运行中)。但是,如果我在浏览器中访问http://localhost:3000/fail/async
,浏览器就会生气(Chrome显示一个“Node : Error 324,net::ERR_EMPTY_RESPONSE:服务器在没有发送任何数据的情况下关闭连接”消息),因为节点进程已经退出,在我调用它的终端上显示了对stdout的回溯跟踪。
发布于 2014-03-02 11:49:23
为了能够捕获异步错误,我使用域。使用Express,您可以尝试以下代码:
function domainWrapper() {
return function (req, res, next) {
var reqDomain = domain.create();
reqDomain.add(req);
reqDomain.add(res);
res.on('close', function () {
reqDomain.dispose();
});
reqDomain.on('error', function (err) {
next(err);
});
reqDomain.run(next)
}
}
app.use(domainWrapper());
//all your other app.use
app.use(express.errorHandler());
此代码将使您的异步错误被捕获并发送到错误处理程序。在本例中,我使用express.errorHandler,但它适用于任何处理程序。
有关域的更多信息:http://nodejs.org/api/domain.html
发布于 2012-04-30 22:44:55
您可以使用表示使用的默认错误处理程序(实际上是连接错误处理程序 )。
var app = require('express').createServer();
app.get('/', function(req, res){
throw new Error('Error thrown here!');
});
app.configure(function(){
app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));
});
app.listen(3000);
代码的更新,您实际上需要捕获错误并传递给它,以便像这样表示
var express = require('express');
var http = require('http');
var app = express.createServer();
app.get('/', function (req, res, next) {
console.log("debug", "calling");
var options = {
host:'www.google.com',
port:80,
path:"/"
};
http.get(options,
function (response) {
response.on("data", function (chunk) {
try {
console.log("data: " + chunk);
chunk.call(); // no such method; throws here
}
catch (err) {
return next(err);
}
});
}).on('error', function (e) {
console.log("error connecting" + e.message);
});
});
app.configure(function () {
app.use(express.errorHandler({ dumpExceptions:true, showStack:true }));
});
app.listen(3000);
https://stackoverflow.com/questions/10390658
复制相似问题