Node.js отличительные ошибки при создании запроса HTTP
My node.js приложение использует http.request
для REST API http://army.gov/launch-nukes
, и мне нужно различать три возможных случая:
-
Success
- сервер отвечает утвердительно. Я знаю, что мои враги уничтожены.
-
Failure
- либо я получил ошибку с сервера, либо не смог подключиться к серверу. У меня все еще есть враги.
-
Unknown
- После установления соединения с сервером я отправил запрос, но не уверен, что произошло. Это может означать, что запрос никогда не попадал на сервер, или ответ сервера мне никогда не делал. Я мог или не мог только начать мировую войну.
Как вы можете видеть, мне очень важно различать случай Failure
и Unknown
, так как они имеют очень разные последствия и разные действия, которые мне нужно предпринять.
Я также очень хотел бы использовать http Keep-Alive - как я могу сказать, я немного сторонник войны и планирую делать много запросов в очередях (а затем ничего не надолго времени)
-
Ядро вопроса состоит в том, как отделить сообщение-ошибка/тайм-аут (который является Failure
) от ошибки/таймаута, которая возникает после того, как запрос помещается на провод (который является Unknown
).
В логике psuedo-code я хочу:
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 */);
}
)
Ответы
Ответ 1
Вот пример:
var http = require('http');
var options = {
hostname: 'localhost',
port: 7777,
path: '/',
method: 'GET'
};
var req = http.request(options, function (res) {
if (('' + req.statusCode).match(/^2\d\d$/)) {
// Request handled, happy
} else if (('' + req.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
(и так далее...)
Ответ 2
Обычно это код состояния 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 будет неудачей. Неизвестно, что callback никогда не будет вызван.
Если API, который вы описываете, не соответствует стандартным кодам ответа, я не знаю. Вам нужно будет посмотреть документы.