web-dev-qa-db-ja.com

node.jsでHTTPクライアント要求の例外をキャッチする方法

特定のサイトが稼働していて適切な応答コードを返すかどうかを確認するために使用したいnode.jsアプリがあります。ドメイン名が解決していないか、リクエストがタイムアウトしているために発生するエラーをキャッチできるようにしたいと思います。問題は、これらのエラーによりNodeが発生することです。この非同期プログラミング手法全体は初めてなので、try/catchステートメントをどこに配置すればよいかわかりません。

/ check/site1のようなものに行くajax呼び出しがあります。接続を確立してstatusCodeを返すことを試みる関数を呼び出すサーバー側。これは非常に単純な関数であり、各行を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呼び出しに返すことができるようにしたいと思います。

次に何を試すべきかについての推奨事項はありますか?

37
mattmcmanus

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();
60
robertjd

同様の問題を調査しているときに、別のソリューションに出くわしました。何らかの理由で接続を確立できない場合、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");

もちろん、接続エラーとリクエストへの応答は両方とも非同期に到着するため、単にリクエストを返すだけでは機能しません。代わりに、イベントハンドラー内からの結果を呼び出し元に通知する必要があります。

11
Sarah Roberts

残念ながら、現時点ではこれらの例外を直接キャッチする方法はありません。すべてのものがバックグラウンドで非同期に発生するためです。

できることは、自分で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の安定化に焦点が当てられているようです。 jsは主にサーバーであるため、スループットが重要です。

バグを報告する が可能ですが、クラッシュなどは機能よりも優先順位が高く、ほとんどの新しい機能はforkプルリクエストを介してそれを実現します。

Node.jsの現在のロードマップについては、Ryan Dahl(Nodeの作成者)によるこの講演をご覧ください。
http://developer.yahoo.com/yui/theater/video.php?v=yuiconf2010-dahl

9
Ivo Wetzel