【问题标题】:Is it possible to catch the exception generated by trying to connect to a bad url?是否可以捕获通过尝试连接到错误的 url 产生的异常?
【发布时间】:2012-04-20 15:27:10
【问题描述】:

使用 node http 包似乎无法捕获由打开错误 URL 引起的异常。这是一个问题,因为它会杀死我的集群,我想保证它会永远存在

代码如下:(使用fibers.promise)

function openConnection(dest, port, contentType, method, throwErrorOnBadStatus)
{
  "use strict";
  assert.ok(dest, "generalUtilities.openConnection: dest is null");
  //dest = dest.replace('//','/');
  console.log('opening connection: ' + dest + " contentType: " + contentType);
  var prom = promise(),
    errProm = promise(),
    ar = [],
    urlParts = url.parse(dest),
    httpClient,
    req,
    got,
    res;
  //console.log('urlParts.port: ' + urlParts.port);
  if (port) {
    urlParts.port = port;
  } else if (!urlParts.port) {
    urlParts.port = 80;
  }
  if (contentType) {
    urlParts.accept = contentType;
  } else {
    urlParts.contentType = 'text/html';
  }
  if (!urlParts.method) {
    if (method) {
      urlParts.method = method;
    } else {
      urlParts.method = 'GET';
    }
  }
  try {
    httpClient = http.createClient(urlParts.port, urlParts.hostname);
    req = httpClient.request(urlParts.method, urlParts.path, urlParts);
  //console.log('req: ' + req);
  //if (req.connection) {
  //  req.connection.setTimeout(HTTP_REQUEST_TIMEOUT);
  //}
  //else {
  //  throw new Error ("No Connection Established!");
  //}
      req.end();
    req.on('response', prom);
    req.on('error', errProm);
    got = promise.waitAny(prom, errProm);
    if (got === errProm) {
      //assert.ifError(errProm.get(), HTTP_REQUEST_TIMEOUT_MSG + dest);
      throw new Error(HTTP_REQUEST_TIMEOUT_MSG + dest + ': ' + got.get());
    }
    res = prom.get();
    ar.res = res;
    ar.statusCode = res.statusCode;
    if (ar.statusCode >= 300 && throwErrorOnBadStatus) {
      assert.ifError("page not found!");
    }
    return ar;
  }
  catch (err) {
    console.log(err);
  }
}

这是我的测试方法

var promise = require('fibers-promise');
var gu = require("../src/utils/generalutilities.js");

var brokenSite = 'http://foo.bar.com:94//foo.js';
promise.start(function () {
  try {
    gu.openConnection(brokenSite, null, null, "GET", true);
  }
  catch (err) {
    console.log('got: ' + err);
  }
});

当我运行这段代码时,我得到:

错误:getaddrinfo ENOENT。它永远不会被 try catch 捕获

【问题讨论】:

  • 以后请使用正确的代码格式。您只需将整个代码块缩进四个空格。不要使用<pre><code>
  • 那么,错误的堆栈跟踪是什么?

标签: javascript node.js try-catch


【解决方案1】:

在为请求提供错误处理程序时,它适用于我:

req.on('error', errorHandler);

我看到你也这样做了,但是你在发布后设置了它

req.end();

您可以在附加错误处理程序后尝试发出end() 吗?

顺便说一句,我真的推荐request,因为它可以通过合理的默认值处理此类问题。使用起来真的很轻松。

编辑:这是一个简单的示例,显示附加错误处理程序让我可以处理 ENOENT/ENOTFOUND 错误:

var http = require('http');

var req = http.request({hostname: 'foo.example.com'}, function(err, res) {
    if(err) return console.error(err);
    console.log('got response!');
});

req.on('error', function(err) {
    console.error('error!', err);
});

另一条有价值的信息:我不确定它如何与纤维结合,但总的来说,您应该永远在 nodejs 异步代码中throw。它很少按照你想要的方式工作。相反,使用将任何错误作为第一个参数传递给下一个回调的标准做法,并在有意义的地方处理错误(通常,在调用链的上层,您可以对它做一些明智的事情)。

【讨论】:

  • 移动我的结束语句不起作用,但我使用请求让它工作 - 我同意这个库为基本的 http 包增加了很多!
【解决方案2】:

您可以抓取页面以获取错误代码。

【讨论】:

  • 它甚至从未进入页面。它用 getaddrinfo ENOENT 让我失望
猜你喜欢
  • 1970-01-01
  • 2012-07-12
  • 1970-01-01
  • 2019-06-29
  • 1970-01-01
  • 2013-01-18
  • 2021-06-08
  • 1970-01-01
  • 2017-12-03
相关资源
最近更新 更多