1

使用 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 捕获

4

2 回答 2

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);
});

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

于 2012-04-20T16:04:01.020 回答
0

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

于 2012-04-20T15:28:54.820 回答