Node.js
Uitzondering afhandeling
Zoeken…
Behandeling van uitzonderingen in Node.Js
Node.js heeft 3 basismanieren om met uitzonderingen / fouten om te gaan:
- probeer - blok vangen
- fout als het eerste argument voor een
callback
-
emit
een foutgebeurtenis behulp eventEmitter
try-catch wordt gebruikt om de uitzonderingen van de synchrone code-uitvoering te vangen. Als de beller (of de beller van de beller, ...) try / catch heeft gebruikt, kan de fout worden opgevangen. Als geen van de bellers try-catch had, crasht het programma.
Als het gebruik van try-catch bij een async-bewerking en een uitzondering is veroorzaakt door callback van de async-methode, wordt het niet gepakt door try-catch. Om een uitzondering van de callback van de asynchrone bewerking op te vangen, worden bij voorkeur beloftes gebruikt .
Voorbeeld om het beter te begrijpen
// ** 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
callbacks worden meestal gebruikt in Node.js omdat callback een gebeurtenis asynchroon levert. De gebruiker geeft u een functie door (de terugbelopdracht) en u roept deze ergens later op wanneer de asynchrone bewerking is voltooid.
Het gebruikelijke patroon is dat de callback wordt opgeroepen als een callback (fout, resultaat) , waarbij slechts één van fout en resultaat niet nul is, afhankelijk van of de bewerking is geslaagd of mislukt.
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 Voor meer gecompliceerde gevallen kan de functie zelf in plaats van een callback te gebruiken een EventEmitter-object retourneren en wordt van de beller verwacht dat deze luistert naar foutgebeurtenissen op de emitter.
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
});
Onbehandeld uitzonderingsbeheer
Omdat Node.js op een enkel proces draait, zijn niet-opgevangen uitzonderingen een aandachtspunt bij het ontwikkelen van applicaties.
Uitzonderingen stil verwerken
De meeste mensen laten node.js server (s) de fouten stilletjes opslokken.
- Zwijgend omgaan met de uitzondering
process.on('uncaughtException', function (err) {
console.log(err);
});
Dit is slecht , het zal werken maar:
De hoofdoorzaak blijft onbekend, omdat deze niet bijdraagt aan het oplossen van de oorzaak van de uitzondering (fout).
In het geval van een database-verbinding (pool) wordt om de een of andere reden gesloten, zal dit resulteren in een constante verspreiding van fouten, wat betekent dat de server actief is, maar niet opnieuw verbinding maakt met db.
Terugkeren naar de oorspronkelijke status
In het geval van een "uncaughtException" is het goed om de server opnieuw op te starten en terug te brengen naar de oorspronkelijke staat , waarvan we weten dat deze zal werken. Uitzondering wordt vastgelegd, applicatie wordt beëindigd, maar omdat deze wordt uitgevoerd in een container die ervoor zorgt dat de server actief is, zullen we de server opnieuw opstarten (terugkeren naar de oorspronkelijke werkstatus).
- De forever (of andere CLI-tool installeren om ervoor te zorgen dat de knooppuntserver continu werkt)
npm install forever -g
- De server voor altijd opstarten
forever start app.js
De reden waarom het is gestart en waarom we voor altijd gebruiken is nadat de server voor altijd is beëindigd, het proces de server opnieuw start.
- De server opnieuw opstarten
process.on('uncaughtException', function (err) {
console.log(err);
// some logging mechanisam
// ....
process.exit(1); // terminates process
});
Een kanttekening was dat er ook een manier was om uitzonderingen met Clusters en domeinen af te handelen.
Domeinen worden afgekeurd meer informatie hier .
Fouten en beloften
Beloften behandelen fouten anders dan synchrone of callback-gestuurde code.
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!
});
momenteel leiden fouten die in een belofte worden gegooid die niet worden opgevangen, tot het slikken van de fout, wat het moeilijk kan maken om de fout op te sporen. Dit kan worden opgelost met behulp van linting tools zoals eslint of door ervoor te zorgen heb je altijd een catch
clausule.
Dit gedrag is verouderd in knooppunt 8 ten gunste van het beëindigen van het knooppuntproces.