177 votes

Principes de gestion des erreurs pour les applications Node.js + Express.js ?

Il semble que les rapports d'erreurs soient traités différemment dans Node.js+. Express.js par rapport à d'autres cadres. Ai-je bien compris que cela fonctionne comme suit ?

A) Détecter en les recevant en tant que paramètres de vos fonctions de rappel. Par exemple :

doSomethingAndRunCallback(function(err) { 
    if(err) { … }
});

B) Rapport les erreurs dans MIDDLEWARE en appelant next(err). Exemple :

handleRequest(req, res, next) {
    // An error occurs…
    next(err);
}

C) Rapport les erreurs dans les ROUTES en lançant l'erreur. Exemple :

app.get('/home', function(req, res) {
    // An error occurs
    throw err;
});

D) Poignée en configurant votre propre gestionnaire d'erreurs via app.error() ou en utilisant le gestionnaire d'erreurs générique de Connect. Exemple :

app.error(function(err, req, res, next) {
    console.error(err);
    res.send('Fail Whale, yo.');
});

Ces quatre principes sont-ils la base de tout traitement/rapport d'erreur dans les applications Node.js+Express.js ?

183voto

Raynos Points 82706

La gestion des erreurs dans Node.js est généralement du type A). La plupart des callbacks renvoient un objet d'erreur comme premier argument ou null .

Express.js utilise des intergiciels et la syntaxe des intergiciels utilise les points B) et E) (mentionnés ci-dessous).

C) est une mauvaise pratique, si vous voulez mon avis.

app.get('/home', function(req, res) {
    // An error occurs
    throw err;
});

Vous pouvez facilement réécrire ce qui précède sous la forme

app.get('/home', function(req, res, next) {
    // An error occurs
    next(err);
});

La syntaxe de l'intergiciel est valable dans un get demande.

Quant à D)

(07:26:37 PM) tjholowaychuk : app.error est supprimé dans la version 3.x

TJ vient de le confirmer app.error est obsolète en faveur de E

E)

app.use(function(err, req, res, next) {
  // Only handle `next(err)` calls
});

Tout intergiciel ayant une longueur de 4 (4 arguments) est considéré comme un intergiciel d'erreur. Lorsque l'on appelle next(err) connect va et appelle l'intergiciel basé sur les erreurs.

11voto

Les collaborateurs de Joyent ont publié un document très instructif sur les meilleures pratiques sur ce point. Un article à lire absolument pour tout développeur Node.js.

3voto

David Points 35

Pourquoi un premier paramètre ?

En raison de la nature asynchrone de Node.js, la fonction premier-paramètre-comme-err Le modèle est devenu une convention bien établie pour les userland Node.js gestion des erreurs . Ceci est dû au fait qu'il s'agit d'un système asynchrone :

try {
    setTimeout(function() {
        throw 'something broke' //Some random error
    }, 5)
}
catch(e) {
   //Will never get caught
}

Ainsi, le fait d'avoir le premier argument de la callback est à peu près le seul moyen raisonnable de transmettre des erreurs de manière asynchrone, à part les jeter.

Le non-respect de cette règle entraînera une unhandled exception ce qui, à première vue, implique que rien n'a été fait pour sortir l'application de son état de confusion.

Les exceptions, pourquoi existent-elles ?

Il convient toutefois de noter que pratiquement toutes les parties de Node.js sont des émetteurs d'événements et que le lancement d'une exception est un événement de bas niveau qui peut être géré comme tous les autres événements :

//This won't immediately crash if connection fails
var socket = require("net").createConnection(5000);
socket.on("error", function(err) {
    console.error("calm down...", err)
});

Le présent peut mais ne doit pas être poussée à l'extrême pour attraper toutes les erreurs et créer une application qui s'efforcera de ne jamais planter. C'est une idée terrible dans presque tous les cas d'utilisation, parce que le développeur n'aura aucune idée de ce qui se passe dans l'état de l'application et que c'est analogue à envelopper main dans try-catch.

Domaines - regroupement logique des événements

Dans le cadre du traitement de ce problème d'exceptions, les applications tombent en panne, domaines permettent au développeur de prendre, par exemple, l'application Express.js, et d'essayer de fermer les connexions de manière raisonnable en cas de défaillance catastrophique.

ES6

Il est probablement mentionné que cela changera à nouveau car ES6 permet au modèle de générateur de créer des événements asynchrones qui sont toujours rattrapables avec des blocs try/catch.

Koa (écrit par TJ Holowaychuck, le même auteur original d'Express.js) le fait remarquablement. Il utilise le langage ES6 yield pour créer des blocs qui, tout en semblant presque synchrones, sont traités de manière asynchrone, comme c'est habituellement le cas pour les nœuds :

app.use(function *(next) {
    try {
        yield next;
    } 
    catch (err) {
        this.status = err.status || 500;
        this.body = err.message;
        this.app.emit('error', err, this);
    }
});

app.use(function *(next) {
    throw new Error('some error');
})

Cet exemple a été volé sans vergogne à ici .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X