web-dev-qa-db-ja.com

httpリクエストを行う際のnode.jsの識別エラー

私のnode.jsアプリケーションはhttp.requestをREST API http://army.gov/launch-nukesに使用しているため、次の3つのケースを区別する必要があります。

  • Success-サーバーは肯定で応答します。私は敵が破壊されたことを知っています。
  • Failure-サーバーからエラーを受け取ったか、またはサーバーに接続できませんでした。私にはまだ敵がいます。
  • Unknown-サーバーへの接続を確立した後、リクエストを送信しましたが、何が起こったのかわかりません。これは、リクエストがサーバーに送信されなかったか、サーバーへの応答が送信されなかったことを意味します。私は世界大戦を始めたかもしれませんし、していないかもしれません。

ご覧のとおり、FailureUnknownのケースを区別することは非常に重要です。これらは非常に異なる結果と私がとる必要がある異なるアクションを持っているからです。

また、http Keep-Aliveを使用したいと思います-私が言うことができるように、私はちょっとした戦争商人であり、バーストで大量のリクエストを作成する予定です(そして長期間は何もしません)

-

質問の核心は、接続エラー/タイムアウト(Failure)を、要求がワイヤに置かれた後に発生するエラー/タイムアウト(Unknown)。

擬似コードロジックでは、これが必要です。

var tcp = openConnectionTo('army.gov') // start a new connection, or get an kept-alive one
tcp.on('error', FAILURE_CASE);
tcp.on('connectionEstablished',  function (connection) {

       var req = connection.httpGetRequest('launch-nukes');
       req.on('timeout', UNKNOWN_CASE);
       req.on('response', /* read server response and decide FAILURE OR SUCCESS */);
   }
)
24
Heptic

次に例を示します。

var http = require('http');

var options = {
  hostname: 'localhost',
  port: 7777,
  path: '/',
  method: 'GET'
};

var req = http.request(options, function (res) {
  // check the returned response code
  if (('' + res.statusCode).match(/^2\d\d$/)) {
    // Request handled, happy
  } else if (('' + res.statusCode).match(/^5\d\d$/))
    // Server error, I have no idea what happend in the backend
    // but server at least returned correctly (in a HTTP protocol
    // sense) formatted response
  }
});

req.on('error', function (e) {
  // General error, i.e.
  //  - ECONNRESET - server closed the socket unexpectedly
  //  - ECONNREFUSED - server did not listen
  //  - HPE_INVALID_VERSION
  //  - HPE_INVALID_STATUS
  //  - ... (other HPE_* codes) - server returned garbage
  console.log(e);
});

req.on('timeout', function () {
  // Timeout happend. Server received request, but not handled it
  // (i.e. doesn't send any response or it took to long).
  // You don't know what happend.
  // It will emit 'error' message as well (with ECONNRESET code).

  console.log('timeout');
  req.abort();
});

req.setTimeout(5000);
req.end();

Netcatを使用してプレイすることをお勧めします。

$ nc -l 7777
// Just listens and does not send any response (i.e. timeout)

$ echo -e "HTTP/1.1 200 OK\n\n" | nc -l 7777
// HTTP 200 OK

$ echo -e "HTTP/1.1 500 Internal\n\n" | nc -l 7777
// HTTP 500

(等々...)

33
kamituel

これは通常、APIステータスコードにあります。リクエストパッケージでは、次のようにアクセスできます。

request('http://www.google.com', function (error, response, body) {
   if (!error && response.statusCode == 200) {
       console.log(body) // Print the google web page.
   }
})

response.statusCode 200は、機能したことを意味します。 500は失敗になります。不明なコールバックは決して呼び出されません。

説明しているAPIが標準の応答コードに従っていない場合、わかりません。ドキュメントを見る必要があります。