web-dev-qa-db-fra.com

Comment intercepter les exceptions de demande de client http dans node.js

J'ai une application node.js que je veux utiliser pour vérifier si un site particulier est en place et renvoyer le bon code de réponse. Je veux pouvoir détecter les erreurs qui surviennent lorsque le nom de domaine ne se résout pas ou que la demande arrive à expiration. Le problème est que ces erreurs provoquent une panne de Node. Je suis nouveau dans toute cette méthodologie de programmation asynchrone, donc je ne sais pas où placer mes instructions try/catch.

J'ai un appel ajax qui va vers quelque chose comme/check/site1. Côté serveur qui appelle une fonction qui tente d'établir une connexion, puis renvoie le statusCode. C'est une fonction très simple, et j'ai encapsulé chaque ligne dans un try/catch et elle n'attrape jamais rien. C'est ici:

function checkSite(url){
    var site = http.createClient(80, url);
    var request = site.request('GET', '/', {'Host': url});
    request.end();
    return request;
  }

Même avec chacune de ces lignes enveloppées dans un try/catch, j'obtiendrai toujours des exceptions non capturées comme EHOSTUNREACH et ainsi de suite. Je veux pouvoir les attraper et les renvoyer à l'appel ajax.

Des recommandations sur quoi essayer ensuite?

37
mattmcmanus

http.createClient est obsolète.

Voici un exemple rapide de gestion des erreurs à l'aide du nouveau http.request:

var http = require("http");

var options = {
    Host : "www.example.com"
};

var request = http.request(options, function(req) {
    ...
});
request.on('error', function(err) {
    // Handle error
});

request.end();
60
robertjd

Je suis tombé sur une autre solution pendant que je recherchais un problème similaire. http.Client émet un événement "erreur" si une connexion ne peut pas être établie pour une raison quelconque. Si vous gérez cet événement, l'exception ne sera pas levée:

var http = require('http');
var sys = require('sys');

function checkSite(url) {
    var site = http.createClient(80, url);
    site.on('error', function(err) {
        sys.debug('unable to connect to ' + url);
    });
    var request = site.request('GET', '/', {'Host': url});
    request.end();
    request.on('response', function(res) {
        sys.debug('status code: ' + res.statusCode);
    });
}

checkSite("www.google.com");
checkSite("foo.bar.blrfl.org");

Bien sûr, l'erreur de connexion et la réponse à la demande arrivent toutes deux de manière asynchrone, ce qui signifie que le simple retour de la demande ne fonctionnera pas. Au lieu de cela, vous devez informer l'appelant des résultats à partir des gestionnaires d'événements.

11
Sarah Roberts

Malheureusement, pour le moment, il n'y a aucun moyen d'attraper ces exceptions directement, car tout se passe de manière asynchrone en arrière-plan.

Tout ce que vous pouvez faire est d'attraper les uncaughtException par vous-même:

var http = require('http');

function checkSite(url){
    var site = http.createClient(800, url);
    var request = site.request('GET', '/', {'Host': url});
    request.end();
    return request;
}

process.on('uncaughtException', function (err) {
    console.log(err);
}); 

checkSite('http://127.0.0.1');

Qui dans ce cas (notez le port 800) se connecte:

{ message: 'ECONNREFUSED, Connection refused',
  stack: [Getter/Setter],
  errno: 111,
  syscall: 'connect' }

Node.js est toujours en cours de développement et il y aura certainement beaucoup de progrès au cours des prochains mois, en ce moment, l'accent semble être mis sur la correction des bogues de performances pour 3.x et la stabilisation de l'API, car après tout, Node. js est principalement un serveur, donc le débit est important.

Vous pouvez déposer un bogue cependant, mais soyez averti que les plantages, etc. ont une priorité beaucoup plus élevée que les fonctionnalités, et la plupart des nouvelles fonctionnalités le font via des requêtes d'extraction de fourches.

Également pour la feuille de route actuelle de Node.js, regardez cette conférence de Ryan Dahl (Node's Creator):
http://developer.yahoo.com/yui/theater/video.php?v=yuiconf2010-dahl

9
Ivo Wetzel