Sök…


Hantera undantag i Node.Js

Node.js har tre grundläggande sätt att hantera undantag / fel:

  1. prova - fånga blocket
  2. fel som det första argumentet till ett callback
  3. emit en felhändelse användning eventEmitter

try-catch används för att fånga de undantag som kastas från körningen av synkron kod. Om den som ringer (eller den som ringer upp, ...) använde try / catch, kan de fånga felet. Om ingen av de anropande hade försökt fånga än programmet kraschar.
Om man använder try-catch på en async-operation och undantag kastades från återuppringning av async-metoden än kommer det inte att fångas av try-catch. För att få ett undantag från återuppringning av asynkoperationer föredras det att använda löften .
Exempel för att förstå det bättre

// ** 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

återuppringningar används mest i Node.js eftersom återuppringning levererar en händelse asynkront. Användaren ger dig en funktion (återuppringningen) och du åberopar den någon gång senare när den asynkrona operationen är klar.
Det vanliga mönstret är att återuppringningen anropas som en återuppringning (fel, resultat) , där endast ett av fel och resultat är icke-noll, beroende på om operationen lyckades eller misslyckades.

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 För mer komplicerade fall, istället för att använda ett återuppringning, kan själva funktionen returnera ett EventEmitter-objekt, och den som ringer förväntas lyssna på felhändelser på sändaren.

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
});

Obehandlad undantagshantering

Eftersom Node.js körs på en enda process är undantagna undantag ett problem att vara medvetna om när man utvecklar applikationer.

Tyst hantering av undantag

De flesta människor låter node.js-server (-er) tyst svälja upp felen.

  • Tyst hantering av undantaget
process.on('uncaughtException', function (err) {
  console.log(err);
});

Det här är dåligt , det kommer att fungera men:

  • Rotorsaken kommer att förbli okänd, eftersom den inte kommer att bidra till att lösa vad som orsakade undantaget (fel).

  • Vid databasanslutning (pool) blir av någon anledning stängd kommer detta att resultera i konstant spridning av fel, vilket innebär att servern kommer att köras men den kommer inte att ansluta till db igen.


Återgår till initialtillstånd

I händelse av en "uncovedException" är det bra att starta om servern och återställa den till sitt ursprungliga tillstånd , där vi vet att den kommer att fungera. Undantag är loggat, applikationen avslutas men eftersom det kommer att köras i en behållare som kommer att se till att servern körs uppnår vi omstart av servern (återgår till det ursprungliga arbetsläget).

  • Installera forever (eller annat CLI-verktyg för att se till att nodservern körs kontinuerligt)
npm install forever -g
  • Starta servern för alltid
forever start app.js

Anledning till varför det startas och varför vi använder för evigt är när servern är avslutad för alltid kommer processen att starta servern igen.

  • Starta om servern
process.on('uncaughtException', function (err) {
    console.log(err);

    // some logging mechanisam
    // ....        

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

På en sidnot var det också ett sätt att hantera undantag med kluster och domäner .

Domäner avskrivs mer information här .

Fel och löften

Löften hanterar fel annorlunda än synkron eller återuppringningsdriven kod.

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!
    });

för närvarande resulterar fel som kastas i ett löfte som inte fångas i att felet sväljs, vilket kan göra det svårt att spåra felet. Detta kan lösas med hjälp av luddning verktyg som eslint eller genom att se till att du alltid har en catch klausul.

Detta beteende avskrivs i nod 8 för att avsluta nodprocessen.



Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow