是否可以通过尝试连接到错误的URL来捕获生成的异常?

时间:2012-04-20 15:27:10

标签: javascript node.js try-catch

使用节点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

捕获

2 个答案:

答案 0 :(得分:2)

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

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。它很少以你想要的方式工作。相反,使用将任何错误作为第一个参数传递给下一个回调的标准做法,并在有意义的地方处理错误(通常,在调用链中高位,你可以用它做一些合理的事情)。

答案 1 :(得分:0)

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