Recherche…


Gestion des exceptions dans Node.Js

Node.js dispose de 3 méthodes de base pour gérer les exceptions / erreurs:

  1. essayer - attraper le bloc
  2. erreur comme premier argument d'un callback
  3. emit un événement d' erreur en utilisant eventEmitter

try-catch est utilisé pour intercepter les exceptions lancées à partir de l'exécution du code synchrone. Si l'appelant (ou l'appelant de l'appelant, ...) a essayé / rattrapé, il peut alors détecter l'erreur. Si aucun des appelants n’a essayé, le programme se bloque.
Si vous utilisez try-catch sur une opération asynchrone et que l'exception est renvoyée par le rappel de la méthode asynchrone, elle ne sera pas interceptée par try-catch. Pour intercepter une exception de rappel d'opération asynchrone, il est préférable d'utiliser des promesses .
Exemple pour mieux comprendre

// ** Example - 1  **
function doSomeSynchronousOperation(req, res) {
    if(req.body.username === ''){
        throw new Error('User Name cannot be empty');
    }  
    return true;  
}

// calling the method above
try {
    // synchronous code   
    doSomeSynchronousOperation(req, res)    
catch(e) {
    //exception handled here   
    console.log(e.message);  
} 

// ** Example - 2 **
function doSomeAsynchronousOperation(req, res, cb) {
    // imitating async operation
    return setTimeout(function(){
        cb(null, []);
    },1000);
}
 
try {
    // asynchronous code   
    doSomeAsynchronousOperation(req, res, function(err, rs){
        throw new Error("async operation exception");
    })   
} catch(e) {
     // Exception will not get handled here
     console.log(e.message);  
}
// The exception is unhandled and hence will cause application to break

Les callbacks sont principalement utilisés dans Node.js car le callback délivre un événement de manière asynchrone. L'utilisateur vous transmet une fonction (le rappel) et vous l'appelez plus tard lorsque l'opération asynchrone est terminée.
Le schéma habituel est que le rappel est appelé comme un rappel (err, result) , où un seul des erreurs et des résultats est non nul, selon que l'opération a réussi ou échoué.

function doSomeAsynchronousOperation(req, res, callback) {
   setTimeout(function(){
        return callback(new Error('User Name cannot be empty'));    
   }, 1000);  
   return true;
}

doSomeAsynchronousOperation(req, res, function(err, result) {
   if (err) {
       //exception handled here 
       console.log(err.message);
   }
   
   //do some stuff with valid data
});

emit Pour des cas plus compliqués, au lieu d'utiliser un rappel, la fonction elle-même peut renvoyer un objet EventEmitter, et l'appelant est censé écouter les événements d'erreur sur l'émetteur.

const EventEmitter = require('events');

function doSomeAsynchronousOperation(req, res) {
    let myEvent = new EventEmitter();

    // runs asynchronously
    setTimeout(function(){
        myEvent.emit('error', new Error('User Name cannot be empty'));
    }, 1000);

    return myEvent;
}

// Invoke the function
let event = doSomeAsynchronousOperation(req, res);

event.on('error', function(err) {
    console.log(err);
});

event.on('done', function(result) {
    console.log(result); // true
});

Gestion des exceptions non maîtrisées

Étant donné que Node.js s'exécute sur un seul processus, les exceptions non interceptées constituent un problème à prendre en compte lors du développement d'applications.

Gestion silencieuse des exceptions

La plupart des personnes ont laissé le ou les serveurs node.js avaler les erreurs en silence.

  • Manipulation silencieuse de l'exception
process.on('uncaughtException', function (err) {
  console.log(err);
});

C'est mauvais , ça marchera mais:

  • La cause première restera inconnue, car elle ne contribuera pas à la résolution de ce qui a causé l’exception (erreur).

  • En cas de connexion à une base de données (pool) fermée pour une raison quelconque, cela entraînera une propagation constante des erreurs, ce qui signifie que le serveur fonctionnera mais ne se reconnectera pas à la base de données.


Retourner à l'état initial

En cas d’exception "uncaughtException", il est bon de redémarrer le serveur et de le ramener à son état initial , où nous savons qu’il fonctionnera. L'exception est consignée, l'application est terminée, mais étant donné qu'elle s'exécutera dans un conteneur qui s'assurera que le serveur fonctionne, nous allons redémarrer le serveur (en revenant à son état de fonctionnement initial).

  • Installer le pour toujours (ou un autre outil CLI pour s'assurer que le serveur de noeuds fonctionne en continu)
npm install forever -g
  • Démarrer le serveur pour toujours
forever start app.js

Raison pour laquelle est-il commencé et pourquoi nous utilisons pour toujours est après que le serveur est arrêté pour toujours, le processus va redémarrer le serveur.

  • Redémarrer le serveur
process.on('uncaughtException', function (err) {
    console.log(err);

    // some logging mechanisam
    // ....        

    process.exit(1); // terminates process
});

Sur un côté, il y avait un moyen de gérer les exceptions avec les clusters et les domaines .

Les domaines sont obsolètes plus d'informations ici .

Erreurs et promesses

Les promesses traitent les erreurs différemment du code synchrone ou du code de rappel.

const p = new Promise(function (resolve, reject) {
    reject(new Error('Oops'));
});

// anything that is `reject`ed inside a promise will be available through catch
// while a promise is rejected, `.then` will not be called
p
    .then(() => {
        console.log("won't be called");
    })
    .catch(e => {
        console.log(e.message); // output: Oops
    })
    // once the error is caught, execution flow resumes
    .then(() => {
        console.log('hello!'); // output: hello!
    });

Actuellement, les erreurs dans une promesse qui ne sont pas détectées entraînent une erreur, ce qui peut rendre difficile le suivi de l'erreur. Cela peut être résolu en utilisant des outils de peluches comme eslint ou en vous assurant de toujours avoir une clause de catch .

Ce comportement est obsolète dans le noeud 8 en faveur de la fin du processus de noeud.



Modified text is an extract of the original Stack Overflow Documentation
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow