ti-enxame.com

Capturando ECONNREFUSED em node.js com http.request?

Estou tentando detectar erros ECONNREFUSED ao usar um cliente HTTP em node.js. Estou fazendo pedidos como este:

var http = require('http');
var options = { Host: 'localhost', port: '3301', path: '/', method: 'GET' };

http.request(options).on('response', function (res) {
  // do some stuff
});

Não consigo descobrir como detectar este erro:

Error: connect ECONNREFUSED
  at errnoException (net.js:614:11)
  at Object.afterConnect [as oncomplete] (net.js:605:18)

Se eu faço request.on('error', function () {});, ele não pega. Se eu fizer assim:

var req = request.on(etc)
req.on('error', function blah () {});

Então eu obtenho TypeError: Object false has no method 'on'.

Eu realmente tenho que fazer um erro não detectado de nível superior para lidar com isso? No momento, tudo o que eu faço, todo o meu processo é encerrado.

Edit: encontrei algumas postagens de blog sobre como fazer isso criando um objeto connection, chamando request nele e, em seguida, vinculando a erros no objeto connection, mas não isso não torna o atalho http.request() inteiro inútil?

18
Cera

Alguma razão pela qual você não está usando http://nodejs.org/docs/v0.6.5/api/http.html#http.request como sua base? Experimente isto:

var req = http.request(options, function(res) {
  // Bind 'data', 'end' events here
});

req.on('error', function(error) {
  // Error handling here
});

req.end();
23
Ryan Olds

Cada chamada a http.request() retorna a si mesma. Então tente assim ...

http.request(options.function(){}).on('error',function(){}).end();
6
deezgz

Eu tenho uma solução para isso, depois de tentar todas as sugestões nesta (e em muitas outras) páginas.

Meu cliente precisa detectar um produto pronto para uso que executa janelas incorporadas. O cliente é atendido de uma máquina diferente para o turnkey.

O turnkey pode estar em 3 estados:

  1. desligado
  2. inicializado no Windows, mas não executando o aplicativo turnkey
  3. executando o aplicativo turnkey

Meu cliente envia uma mensagem GET 'encontre o produto pronto para uso' para meu serviço nodejs/express, que então tenta encontrar o produto pronto para uso via http.request. O comportamento de cada um dos 3 casos de uso é;

  1. tempo esgotado
  2. ECONNREFUSADO - porque a fase integrada do Windows do turnkey está recusando conexões.
  3. resposta normal ao pedido (cenário de dia feliz)

O código abaixo lida com todos os 3 cenários. O truque para capturar o evento ECONNREFUSED era aprender que seu manipulador se vincula ao evento de soquete.

var http = require('http');
var express = require('express');
var url = require('url');


function find (req, res) {
    var queryObj = url.parse(req.url, true).query;

    var options = {
        Host: queryObj.ip, // client attaches ip address of turnkey to url.
        port: 1234,
        path: '/some/path',
    }; // http get options

    var badNews = function (e) {
        console.log (e.name + ' error: ', e.message);
        res.send({'ok': false, 'msg': e.message});
    }; // sends failure messages to log and client  

    // instantiate http request object and fire it
    var msg = http.request(options, function (response) {
        var body = '';

        response.on ('data', function(d) {
            body += d;
        }); // accumulate response chunks  

        response.on ('end', function () {
            res.send({'ok': true, 'msg': body});
            console.log('sent ok');
        }); // done receiving, send reply to client

        response.on('error', function (e) {
            badNews(e);
        }); // uh oh, send bad news to client   
    });

    msg.on('socket', function(socket) { 
        socket.setTimeout(2000, function () {   // set short timeout so discovery fails fast
            var e = new Error ('Timeout connecting to ' + queryObj.ip));
            e.name = 'Timeout';
            badNews(e);
            msg.abort();    // kill socket
        });
        socket.on('error', function (err) { // this catches ECONNREFUSED events
            badNews(err);
            msg.abort();    // kill socket
        });
    }); // handle connection events and errors

    msg.on('error', function (e) {  // happens when we abort
        console.log(e);
    });

    msg.end();
}
5
VorpalSword