2011-12-05 15 views
16

Estoy tratando de detectar los errores ECONNREFUSED cuando uso un cliente HTTP en node.js. Estoy haciendo peticiones como esto:Captura ECONNREFUSED en node.js con http.request?

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

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

no puedo encontrar la manera de atrapar a este error:

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

Si hago request.on('error', function() {});, no cogerlo. Si lo hago así:

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

en cuando me siento TypeError: Object false has no method 'on'.

¿Realmente tengo que hacer un error de nivel superior no capturado para hacer frente a esto? Por el momento todo lo que hago, todo mi proceso se cierra.

Edición: He encontrado algunas entradas de blog sobre cómo hacerlo mediante la creación de un objeto connection, llamando request en eso, y luego unirse a errores en el objeto connection, pero ¿no lo hace todo el http.request() acceso directo inútil?

+2

Me di cuenta de esto. Es porque estaba haciendo esto: var req = http.solicitud (opciones) .on ('respuesta', función (res) { // hacer algunas cosas }). end(); req.on ('error', handleError); Estaba llamando a la llamada después de llamar a fin(). Facepalm! – Cera

+0

Para vistas futuras, ¿podría publicar un enlace a esa publicación de blog? Creo que sería muy útil tener aquí. – CSilivestru

Respuesta

17

¿Alguna razón por la que no está usando http://nodejs.org/docs/v0.6.5/api/http.html#http.request como su base? Pruebe esto:

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

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

req.end(); 
+0

no funciona

var req = http.request("http://www.google.com/index.html", function(res) { console.log("Got response: " + res.statusCode); // Bind 'data', 'end' events here }); req.on('error', function(error) { console.log(error) // Error handling here }); req.end();
Codefor

+0

¿Ha intentado con un objeto de opciones válido en lugar de pasar una url como primer parámetro? –

+1

Usando el nodo 10 y puedo confirmar que esta solución funciona controlando el error ECONNREFUSE. – Nucleon

2

Cada llamada a http.request() devuelve su auto. lo tanto, tratar como esto ...

http.request(options.function(){}).on('error',function(){}).end(); 
+0

¡Solución simple! ¡Gracias! –

2

Tengo una solución para esto, después de haber intentado todas las sugerencias en este (y muchos otros) páginas.

Mi cliente necesita detectar un producto listo para usar que ejecute ventanas integradas. El cliente recibe el servicio desde una máquina diferente a la llave en mano.

La llave en mano puede ser en 3 estados:

  1. apagado
  2. arrancará con ventanas, pero no ejecuta la aplicación llave en mano
  3. ejecuta la aplicación llave en mano

Mi cliente envía una 'Encontrar el producto llave en mano' GET mensaje a mi nodejs/express servicio, que luego trata de encontrar el producto llave en mano a través de http.request. El comportamiento para cada uno de los 3 casos de uso es;

  1. tiempo de espera
  2. ECONNREFUSED - porque las ventanas incrustado fase de la llave en mano es conexiones que se niegan.
  3. respuesta normal a petición (escenario feliz día)

El código siguiente se encarga de los 3 escenarios. El truco para atrapar el evento ECONNREFUSED fue aprender que su manejador se une al evento socket.

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(); 
} 
Cuestiones relacionadas