我浏览了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);
Run Code Online (Sandbox Code Playgroud)
崩溃整个应用程序,产生追溯
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)
Run Code Online (Sandbox Code Playgroud)
met*_*att 43
如果您确实希望捕获所有异常并提供除退出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');
});
});
Run Code Online (Sandbox Code Playgroud)
现在,如果我http://localhost:3000/fail/sync
在浏览器中访问,浏览器会转储一个调用堆栈(显示运行中的express.errorHandler).http://localhost:3000/fail/async
但是,如果我在浏览器中访问,则浏览器会生气(Chrome显示"未收到数据:错误324,net :: ERR_EMPTY_RESPONSE:服务器关闭连接而不发送任何数据"消息),因为Node进程已退出,在我调用它的终端上的stdout上显示一个回溯.
小智 10
为了能够捕获异步错误,我使用域.使用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());
Run Code Online (Sandbox Code Playgroud)
此代码将捕获您的异步错误并将其发送到您的错误处理程序.在这个例子中,我使用express.errorHandler,但它适用于任何处理程序.
有关域的更多信息:http://nodejs.org/api/domain.html
您可以使用express使用的默认错误处理程序,它实际上是connect error handler。
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);
Run Code Online (Sandbox Code Playgroud)
更新 对于您的代码,您实际上需要捕获错误并将其传递给这样的表达
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);
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
23122 次 |
最近记录: |