node.js在发出http请求时区分错误

时间:2022-07-01 16:56:55

My node.js application is using http.request to the REST API http://army.gov/launch-nukes and I need to distinguish between three possible cases:

我的node.js应用程序正在使用http.request到REST API http://army.gov/launch-nukes,我需要区分三种可能的情况:

  • Success -- The server replies in the affirmative. I know my enemies are destroyed.
  • 成功 - 服务器回复是肯定的。我知道我的敌人被摧毁了。
  • Failure -- Either I have received error from the server, or was unable to connect to server. I still have enemies.
  • 失败 - 我从服务器收到错误,或者无法连接到服务器。我还有敌人。
  • Unknown -- After establishing a connection to the server, I have sent the request -- but not sure what happened. This could mean the request never made it to the server, or the server response to me never made it. I may or may not have just started a world war.
  • 未知 - 建立与服务器的连接后,我已发送请求 - 但不确定发生了什么。这可能意味着请求从未进入服务器,或者服务器对我的响应从未成功。我可能会或可能不会刚刚开始一场世界大战。

As you can see, it's very important for me to distinguish the Failure and Unknown case, as they have very different consequences and different actions I need to take.

正如您所看到的,区分失败和未知案例对我来说非常重要,因为它们具有非常不同的后果和我需要采取的不同行动。

I would also very much like to use http Keep-Alive -- as what can I say, I'm a bit of a war-monger and plan on making lots of requests in bursts (and then nothing for long periods of time)

我也非常想使用http Keep-Alive - 我可以说,我有点像一个战争贩子,并计划在爆发时提出大量请求(然后很长一段时间都没有)

--

-

The core of the question is how to separate a connection-error/time-out (which is a Failure) from an error/timeout that occurs after the request is put on the wire (which is an Unknown).

问题的核心是如何将连接错误/超时(这是一个失败)与请求放在线路上发生的错误/超时分开(这是一个未知的)。

In psuedo-code logic I want this:

在伪代码逻辑中我想要这个:

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

2 个解决方案

#1


30  

Here is an example:

这是一个例子:

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

I recommend you play with it using netcat, ie.:

我建议你用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

(and so on...)

(等等...)

#2


1  

This is typically in the APIs status code. In the request package you can access it like this

这通常在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 being 200 means that it worked. 500 would be failure. Unknown would be the callback never being called.

response.statusCode为200表示它有效。 500将失败。未知将是永远不会被调用的回调。

If the API you're describing doesn't follow standard response codes, I don't know. You'll have to look at the docs.

如果您描述的API不遵循标准响应代码,我不知道。你必须看看文档。

#1


30  

Here is an example:

这是一个例子:

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

I recommend you play with it using netcat, ie.:

我建议你用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

(and so on...)

(等等...)

#2


1  

This is typically in the APIs status code. In the request package you can access it like this

这通常在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 being 200 means that it worked. 500 would be failure. Unknown would be the callback never being called.

response.statusCode为200表示它有效。 500将失败。未知将是永远不会被调用的回调。

If the API you're describing doesn't follow standard response codes, I don't know. You'll have to look at the docs.

如果您描述的API不遵循标准响应代码,我不知道。你必须看看文档。