Node.js
Ausnahmebehandlung
Suche…
Behandlung von Ausnahmen in Node.Js
Node.js hat drei grundlegende Möglichkeiten, Ausnahmen / Fehler zu behandeln:
- try - catch block
- Fehler als erstes Argument für einen
callback
-
emit
ein Fehlerereignis unter Verwendung eventEmitter
try-catch wird verwendet, um die Ausnahmen der synchronen Codeausführung abzufangen. Wenn der Anrufer (oder der Anrufer des Anrufers ...) try / catch verwendet hat, kann er den Fehler abfangen. Wenn keiner der Anrufer Try-Catch hatte, stürzt das Programm ab.
Wenn Try-Catch für einen asynchronen Vorgang verwendet wird und eine Ausnahme vom Rückruf der asynchronen Methode ausgelöst wurde, wird sie nicht von try-catch abgefangen. Um eine Ausnahme von einem asynchronen Vorgangscallback abzufangen, werden vorzugsweise Versprechungen verwendet .
Beispiel, um es besser zu verstehen
// ** 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 werden meistens in Node.js verwendet, da Callback ein Ereignis asynchron liefert. Der Benutzer übergibt Ihnen eine Funktion (den Rückruf), und Sie rufen sie später auf, wenn der asynchrone Vorgang abgeschlossen ist.
Das übliche Muster ist, dass der Rückruf als Rückruf (err, result) aufgerufen wird, wobei nur err und result nicht null sind, je nachdem, ob die Operation erfolgreich war oder fehlgeschlagen ist.
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 In komplizierteren Fällen kann die Funktion selbst anstelle eines Rückrufs ein EventEmitter-Objekt zurückgeben, und es wird erwartet, dass der Aufrufer auf Fehlerereignisse auf dem Emitter wartet.
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
});
Unhanded Exception Management
Da Node.js in einem einzelnen Prozess ausgeführt wird, müssen nicht erfasste Ausnahmen beim Entwickeln von Anwendungen berücksichtigt werden.
Ausnahmen stumm behandeln
Die meisten Leute lassen die Fehler von node.js-Servern unbemerkt verschlingen.
- Die Ausnahme wird stumm behandelt
process.on('uncaughtException', function (err) {
console.log(err);
});
Das ist schlecht , es wird aber funktionieren:
Die Ursache wird weiterhin unbekannt bleiben, da dies nicht zur Lösung der Ursache der Ausnahme (Fehler) beiträgt.
Wenn eine Datenbankverbindung (Pool) aus irgendeinem Grund geschlossen wird, führt dies zu einer ständigen Fehlerweitergabe. Dies bedeutet, dass der Server ausgeführt wird, die Verbindung zu db jedoch nicht wiederhergestellt wird.
Rückkehr zum Ausgangszustand
Im Falle einer "uncaughtException" empfiehlt es sich, den Server neu zu starten und in den Ausgangszustand zu versetzen , von dem wir wissen, dass er funktionieren wird. Eine Ausnahme wird protokolliert, die Anwendung wird beendet. Da sie jedoch in einem Container ausgeführt wird, der sicherstellt, dass der Server ausgeführt wird, wird ein Neustart des Servers (Rückkehr zum ursprünglichen Betriebszustand) erreicht.
- Installieren Sie das forever (oder ein anderes CLI-Tool, um sicherzustellen, dass der Knotenserver kontinuierlich ausgeführt wird).
npm install forever -g
- Starten Sie den Server für immer
forever start app.js
Grund, warum es gestartet wird und warum wir für immer verwenden, ist, nachdem der Server für immer beendet wurde. Der Prozess startet den Server erneut.
- Server neu starten
process.on('uncaughtException', function (err) {
console.log(err);
// some logging mechanisam
// ....
process.exit(1); // terminates process
});
Nebenbei gab es eine Möglichkeit, Ausnahmen mit Clustern und Domänen zu behandeln .
Domains sind hier mehr Informationen veraltet.
Fehler und Versprechen
Versprechungen behandeln Fehler anders als synchroner oder Callback-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!
});
Derzeit führen Fehler, die in einem Versprechen eingeworfen werden und nicht erfasst werden, dazu, dass der Fehler verschluckt wird, was die Ermittlung des Fehlers erschweren kann. Dies kann gelöst mit Fusseln Tool wie eslint oder indem sichergestellt haben Sie immer eine catch
- Klausel.
Dieses Verhalten wird in Knoten 8 zugunsten der Beendigung des Knotenprozesses abgelehnt.