【问题标题】:How to catch http client request exceptions in node.js如何在 node.js 中捕获 http 客户端请求异常
【发布时间】:2011-05-18 17:32:42
【问题描述】:

我有一个 node.js 应用程序,我想用它来检查特定站点是否已启动并返回正确的响应代码。我希望能够捕获由于域名未解析或请求超时而出现的任何错误。问题是这些错误会导致 Node 崩溃。我是整个异步编程方法的新手,所以我不确定在哪里放置我的 try/catch 语句。

我有一个类似于 /check/site1 的 ajax 调用。服务器端调用一个尝试建立连接然后返回状态码的函数。这是一个非常简单的函数,我将每一行都包装在一个 try/catch 中,它永远不会捕获任何东西。这里是:

function checkSite(url){
    var site = http.createClient(80, url);
    var request = site.request('GET', '/', {'host': url});
    request.end();
    return request;
  }

即使这些行中的每一行都包含在 try/catch 中,我仍然会遇到未捕获的异常,例如 EHOSTUNREACH 等。我希望能够捕获这些并将其返回给 ajax 调用。

关于下一步要尝试什么有什么建议吗?

【问题讨论】:

    标签: exception-handling node.js express


    【解决方案1】:

    http.createClient 已被弃用。

    以下是如何使用新的http.request 处理错误的快速示例:

    var http = require("http");
    
    var options = {
        host : "www.example.com"
    };
    
    var request = http.request(options, function(req) {
        ...
    });
    request.on('error', function(err) {
        // Handle error
    });
    
    request.end();
    

    【讨论】:

      【解决方案2】:

      我在研究类似问题时偶然发现了另一个解决方案。如果由于任何原因无法建立连接,http.Client 会发出“错误”事件。如果您处理此事件,则不会引发异常:

      var http = require('http');
      var sys = require('sys');
      
      function checkSite(url) {
          var site = http.createClient(80, url);
          site.on('error', function(err) {
              sys.debug('unable to connect to ' + url);
          });
          var request = site.request('GET', '/', {'host': url});
          request.end();
          request.on('response', function(res) {
              sys.debug('status code: ' + res.statusCode);
          });
      }
      
      checkSite("www.google.com");
      checkSite("foo.bar.blrfl.org");
      

      当然,连接错误和对请求的响应都是异步到达的,这意味着简单地返回请求是行不通的。相反,您必须将结果从事件处理程序中通知调用者。

      【讨论】:

        【解决方案3】:

        不幸的是,目前无法直接捕获这些异常,因为所有事情都是在后台异步发生的。

        您所能做的就是自己捕捉uncaughtException

        var http = require('http');
        
        function checkSite(url){
            var site = http.createClient(800, url);
            var request = site.request('GET', '/', {'host': url});
            request.end();
            return request;
        }
        
        process.on('uncaughtException', function (err) {
            console.log(err);
        }); 
        
        checkSite('http://127.0.0.1');
        

        在这种情况下(注意端口 800)记录:

        { message: 'ECONNREFUSED, Connection refused',
          stack: [Getter/Setter],
          errno: 111,
          syscall: 'connect' }
        

        Node.js 仍在大力开发中,在接下来的几个月里肯定会有很大的进步,现在的重点似乎是修复 3.x 的性能错误和使 API 有点稳定,因为之后所有 Node.js 主要是一个服务器,所以吞吐量很重要。

        尽管您可以file a bug,但要注意崩溃等比功能具有更高的优先级,并且大多数新功能都是通过分叉拉取请求实现的。

        对于 Node.js 的当前路线图,请观看 Ryan Dahl(Node 的创建者)的演讲:
        http://developer.yahoo.com/yui/theater/video.php?v=yuiconf2010-dahl

        【讨论】:

        • 信息量最大。回答。曾经。您推荐的是我目前如何设置它,但不是一个选项,因为我将检查多个站点并需要每个站点的响应。我现在将研究其他路线,直到添加更好的异常处理。那些类型的错误只是浮在顶部,这真是令人遗憾。
        • 好吧,正如我在回答的第二部分中所说,没有办法在 ATM 上抓住它。如果您真的需要它,请 fork 节点并添加它,然后执行拉取请求。你不会在问题跟踪器上遇到任何运气,只会崩溃,这样会引起注意。
        • 我希望我可以分叉它并添加该功能,但我什至不知道从哪里开始。
        • 我相信这个功能会在短期内实现,Joyent(托管解决方案)与 Ryan Dahl 达成了一项协议来赞助开发,很快就会有更多的人加入核心团队:)
        【解决方案4】:

        实际上接受的答案更容易:

        function checkSite(url){
        var http = require('http');
        var request = http.get(url,r=>{console.log("OK",r)}).on("error",e=>{
            console.log("ERROR",e)
        })
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-02-12
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多