2010-05-23 6 views
11

J'essaie donc d'écrire un simple serveur socket TCP qui diffuse des informations à tous les clients connectés. Ainsi, lorsqu'un utilisateur se connecte, il est ajouté à la liste des clients et lorsque le flux émet l'événement close, il est supprimé de la liste des clients.Erreurs inaccessibles dans node.js

Cela fonctionne bien, sauf que parfois j'envoie un message au moment où l'utilisateur se déconnecte.

J'ai essayé d'emballer stream.write() dans un bloc try/catch, mais pas de chance. Il semble que l'erreur soit inaccessible.

Répondre

18

La solution consiste à ajouter un écouteur pour l'événement 'error' du flux. Cela peut sembler contre-intuitif au début, mais la justification est saine. Stream.write() envoie des données de manière asynchrone. Au moment où ce nœud s'est rendu compte que l'écriture sur le socket a généré une erreur, votre code s'est déplacé, après l'appel à stream.write, il n'y a donc aucun moyen pour qu'il y ait une erreur. Au lieu de cela, quel noeud dans cette situation émet un événement 'error' du flux, et EventEmitter est codé de sorte que s'il n'y a pas d'écouteurs pour un événement 'error', l'erreur est levée comme exception de premier niveau, et le processus se termine.

+0

Bonne réponse! Ma question supplémentaire ici: quel gestionnaire d'erreur (auditeur) est habituellement supposé faire: juste l'erreur de notation ou appelez également le rappel 'next'? –

14

Peter est tout à fait raison,

et il y a aussi une autre façon, vous pouvez également faire un fourre-tout gestionnaire d'erreurs avec

process.on('uncaughtException',function(error){ 
// process error 
}) 

cela attraper tout ce qui est jeté ...

il est généralement préférable de faire ce chemin de Peter, si possible, mais si vous écrivez, disons, un cadre de test, il peut être une bonne idée d'utiliser process.on('uncaughtException',...

est ici un point essentiel qui couvre (je crois) tous les différents aways d'erreurs de manipulation dans nodejs http://gist.github.com/636290

1

J'ai eu le même problème avec l'exemple de serveur de temps de here Mes clients sont tués et le serveur de temps essaie alors de écrire dans une socket fermée.

La définition d'un gestionnaire d'erreurs ne fonctionne pas car l'événement d'erreur ne se déclenche qu'à la réception. Le serveur de temps ne reçoit pas, (voir la documentation de l'événement de flux).

Ma solution consiste à définir un gestionnaire sur l'événement de fermeture de flux.

stream.on('close', function() { 
    subscribers.remove(stream); 
    stream.end(); 
    console.log('Subscriber CLOSE: ' + subscribers.length + " total.\n"); 
});