2013-10-11 3 views
17

Мой Node.js приложение использует http.request к REST API http://army.gov/launch-nukes и мне нужно различать три возможных случаях:node.js отличающие ошибки при выполнении запроса HTTP

  • Success - сервер отвечает утвердительно , Я знаю, что мои враги уничтожены.
  • Failure - Либо я получил ошибку с сервера, или не удалось подключиться к серверу. У меня все еще есть враги.
  • Unknown - После установления соединения с сервером, я отправил запрос, но не уверен, что произошло. Это может означать, что запрос никогда не попадал на сервер, или ответ сервера мне никогда не делал. Я мог или не мог только начать мировую войну.

Как вы можете видеть, это очень важно для меня, чтобы отличить случай Failure и Unknown, так как они имеют очень разные последствия и разные действия мне нужно предпринять.

Я бы тоже очень хотел использовать 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 */); 
    } 
) 
+0

Можете ли вы предоставить код для запроса? –

+0

На данный момент это стандартная версия 'http.request', но не отличает' Failure' и 'Unknown' – Heptic

+0

. Мой совет: не используйте HTTP-запросы для запуска ядерных ракет. – GregRos

ответ

28

Вот пример:

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 

(и так далее ...)

+0

В версиях 'netcat', которые у меня есть (как' 0.7.1', так и '1.10-39'), вместо этого мне пришлось использовать следующую команду (добавление' -p'): ' nc -l -p 7777' – yorch

+4

Не должно 'req.statusCode' быть' res.statusCode'? – nbppp2

0

Это, как правило, в коде статуса 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, который вы описываете, не соответствует стандартным кодам ответа, я не знаю. Вам нужно будет посмотреть на документы.

+0

Это недопустимо высокая ложная неизвестная скорость. Если сервер не работает, и соединение не может быть установлено - я знаю, что я не начал мировое войну. Я не должен сообщать, что, возможно, я это сделал. – Heptic

+1

Ум. Я думал, что ваш пример Апи был просто шуткой ... но теперь я думаю, что ваш вопрос? Я не понимаю, в чем проблема. Если ваш обратный вызов никогда не получит ничего, он будет тайм-аут. Вот глупый способ http: // stackoverflow.com/questions/6214902/how-to-set-a-timeout-on-a-http-request-in-node –

+3

Проблема в том, что существуют два разных типа тайм-аутов. Один устанавливает соединение tcp. Если вы устанавливаете тайм-ауты соединения tcp, я знаю, что я не выпустил никаких ядер. Если время ответа HTTP, я * может * или, возможно, не уволил ядерное оружие. В этом суть проблемы – Heptic

Смежные вопросы