首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何处理node.js中的代码异常?

如何处理node.js中的代码异常?
EN

Stack Overflow用户
提问于 2012-04-30 21:12:50
回答 4查看 27.9K关注 0票数 28

我查看了Express的文档,描述错误处理的部分对我来说是完全不透明的。

我认为他们所指的app是一个实例createServer(),对吗?但是,我不知道如何在处理请求期间出现异常时阻止node.js破坏应用程序进程。

我真的不需要任何花哨的东西;只要有异常,我只想返回状态500,加上一个空的响应。节点进程不能仅仅因为某个地方有一个未察觉的异常而终止

有没有一个简单的例子说明如何做到这一点?

代码语言:javascript
运行
复制
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);

使整个应用程序崩溃,产生回溯

代码语言:javascript
运行
复制
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)
EN

回答 4

Stack Overflow用户

发布于 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应用程序中:

代码语言:javascript
运行
复制
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的回溯跟踪。

票数 47
EN

Stack Overflow用户

发布于 2014-03-02 11:49:23

为了能够捕获异步错误,我使用域。使用Express,您可以尝试以下代码:

代码语言:javascript
运行
复制
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

票数 10
EN

Stack Overflow用户

发布于 2012-04-30 22:44:55

您可以使用表示使用的默认错误处理程序(实际上是连接错误处理程序 )。

代码语言:javascript
运行
复制
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);

代码的更新,您实际上需要捕获错误并传递给它,以便像这样表示

代码语言:javascript
运行
复制
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);
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10390658

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档