Als ich anfing, mit Express zu arbeiten und herauszufinden, wie ich mit Fehlern umgehen sollte, hatte ich es schwer. Es gab das Gefühl, dass niemand darüber schrieb, was ich brauchte. Infolgedessen musste ich selbst nach Antworten auf meine Fragen suchen. Heute möchte ich alles erzählen, was ich über die Fehlerbehandlung in Express-Anwendungen weiß. Beginnen wir mit synchronen Fehlern.

Synchrone Fehlerbehandlung
Wenn Sie einen synchronen Fehler behandeln müssen, können Sie 
throw mithilfe der 
throw Anweisung 
throw solchen Fehler im Express-Request-Handler auslösen. Bitte beachten Sie, dass Request-Handler auch als "Controller" bezeichnet werden. Ich bevorzuge jedoch die Verwendung des Begriffs "Request-Handler", da mir dies klarer erscheint.
So sieht es aus:
 app.post('/testing', (req, res) => {  throw new Error('Something broke! ') }) 
Solche Fehler können mit dem Express Error Handler abgefangen werden. Wenn Sie keinen eigenen Fehlerbehandler geschrieben haben (wir werden weiter unten darauf eingehen), behandelt Express den Fehler mit dem Standardhandler.
Die Standard-Express-Fehlerbehandlungsroutine führt folgende Aktionen aus:
- Legt den HTTP-Antwortstatuscode auf 500 fest.
- Sendet eine Textantwort an die Entität, die die Anforderung ausführt.
- Protokolliert eine Textantwort an die Konsole.
Fehlermeldung in der Konsole angezeigtAsynchrone Fehlerbehandlung
Um asynchrone Fehler zu behandeln, müssen Sie über das 
next Argument einen Fehler an den Express-Fehlerbehandler senden:
 app.post('/testing', async (req, res, next) => {  return next(new Error('Something broke again! ')) }) 
Dies ist, was auf die Konsole gelangt, wenn dieser Fehler protokolliert wird.
Fehlermeldung in der Konsole angezeigtWenn Sie das Konstrukt async / await in einer Express-Anwendung verwenden, müssen Sie eine Wrapper-Funktion wie 
express-async-handler verwenden . Auf diese Weise können Sie asynchronen Code ohne 
Try / Catch- Blöcke schreiben. Weitere Informationen zu async / await in Express finden Sie 
hier .
 const asyncHandler = require('express-async-handler') app.post('/testing', asyncHandler(async (req, res, next) => {   
Nachdem der Anforderungshandler in den 
express-async-handler , können Sie wie oben beschrieben mit der 
throw Anweisung einen Fehler 
throw . Dieser Fehler wird an den Express-Fehlerbehandler weitergeleitet.
 app.post('/testing', asyncHandler(async (req, res, next) => {  throw new Error('Something broke yet again! ') })) 
Fehlermeldung in der Konsole angezeigtSchreiben Sie Ihren eigenen Fehlerbehandler
Express-Fehlerbehandlungsroutinen verwenden vier Argumente:
- Fehler
- req
- res
- als nächstes
Sie müssen nach Zwischenhandlern und Routen platziert werden.
 app.use() app.get() app.post() app.put() app.delete()  
Wenn Sie eine eigene Fehlerbehandlungsroutine erstellen, verwendet Express die Standard-Fehlerbehandlungsroutine nicht mehr. Um den Fehler zu behandeln, müssen Sie eine Antwort für die Front-End-Anwendung generieren, die den Endpunkt adressiert hat, an dem der Fehler aufgetreten ist. Dies bedeutet, dass Sie Folgendes tun müssen:
- Generieren und senden Sie einen geeigneten Antwortstatuscode.
- Bilden und senden Sie eine passende Antwort.
Welcher Statuscode im Einzelfall angemessen ist, hängt davon ab, was genau passiert ist. Hier ist eine Liste der häufigsten Fehler, auf die Sie vorbereitet sein sollten:
- Fehler 400 Bad RequestFehlerhafte400 Bad Request. Wird in zwei Situationen verwendet. Erstens, wenn der Benutzer das erforderliche Feld nicht in die Anforderung aufgenommen hat (z. B. wurde das Feld mit den Kreditkarteninformationen in dem gesendeten Zahlungsformular nicht ausgefüllt). Zweitens, wenn die Anfrage falsche Daten enthält (z. B. unterschiedliche Passwörter in das Passwortfeld und in das Passwortbestätigungsfeld eingeben).
- Fehler 401 Unauthorized. Dieser Antwortstatuscode wird angewendet, wenn der Benutzer falsche Anmeldeinformationen eingegeben hat (z. B. Benutzername, E-Mail-Adresse oder Kennwort).
- Fehler 403 Forbidden. Wird verwendet, wenn der Benutzer keinen Zugriff auf den Endpunkt hat.
- Fehler 404 Not Found. Es wird in Fällen verwendet, in denen der Endpunkt nicht erkannt werden kann.
- Fehler 500 Internal Server Error. Es wird angewendet, wenn die vom Front-End gesendete Anforderung korrekt generiert wurde, im Back-End jedoch ein Fehler aufgetreten ist.
Nachdem der entsprechende Antwortstatuscode definiert wurde, muss er mit 
res.status :
 app.use((error, req, res, next) => {   
Der Antwortstatuscode sollte der Fehlermeldung entsprechen. Senden Sie dazu den Statuscode zusammen mit dem Fehler.
Am einfachsten geht das mit dem 
http-errors- Paket. Es können drei fehlerhafte Informationen gesendet werden:
- Der Antwortstatuscode.
- Die mit dem Fehler verknüpfte Nachricht.
- Alle Daten, die gesendet werden müssen (dies ist optional).
So installieren Sie das 
http-errors :
 npm install http-errors --save 
So verwenden Sie dieses Paket:
 const createError = require('http-errors')  
Betrachten Sie ein Beispiel, mit dem Sie dies alles richtig verstehen können.
Stellen Sie sich vor, wir versuchen, einen Benutzer unter seiner E-Mail-Adresse zu finden. Dieser Benutzer kann jedoch nicht gefunden werden. Infolgedessen entscheiden wir uns, als Antwort auf die entsprechende Anforderung einen Fehler " 
User not found zu senden, um den Anrufer zu informieren, dass der Benutzer nicht gefunden wurde.
Folgendes müssen wir tun, um den Fehler zu erstellen:
- Setzen Sie den Antwortstatuscode auf 400 Bad Request(schließlich hat der Benutzer falsche Daten eingegeben). Dies wird unser erster Parameter sein.
- Senden Sie eine Nachricht an den Anrufer wie User not found. Dies wird der zweite Parameter sein.
 app.put('/testing', asyncHandler(async (req, res) => {  const { email } = req.body  const user = await User.findOne({ email })   
Sie können den Statuscode mit dem Konstrukt 
error.status und die Fehlermeldung mit 
error.message :
 
Das Ergebnis von Protokollierungsfehlern in der KonsoleAnschließend wird der Antwortstatus mit 
res.status und die Nachricht in 
res.json :
 app.use((error, req, res, next) => {   
Persönlich bevorzuge ich das Senden eines Statuscodes, einer Nachricht und eines Stack-Trace-Ergebnisses für solche Antworten. Dies erleichtert das Debuggen.
 app.use((error, req, res, next) => {   
▍ Standardantwortstatuscode
Wenn die Fehlerquelle nicht 
createError , verfügt sie nicht über die Eigenschaft 
status . Hier ist ein Beispiel, in dem versucht wurde, eine nicht vorhandene Datei mit 
fs.readFile zu lesen:
 const fs = require('fs') const util = require('util')  
Ein solches Fehlerobjekt hat nicht die Eigenschaft 
status :
 app.use((error, req, res, next) => {  console.log('Error status: ', error.status)  console.log('Message: ', error.message) }) 
Das Ergebnis von Protokollierungsfehlern in der KonsoleIn solchen Fällen können Sie den Standardfehlercode festlegen. Wir sprechen nämlich über den 
500 Internal Server Error :
 app.use((error, req, res, next) => {  res.status(error.status || 500)  res.json({    status: error.status,    message: error.message,    stack: error.stack  }) }) 
▍Ändern des Fehlerstatuscodes
Angenommen, wir lesen eine bestimmte Datei anhand der vom Benutzer bereitgestellten Daten. Wenn eine solche Datei nicht existiert, müssen wir einen 
400 Bad Request Fehler 
400 Bad Request . Immerhin kann der Server nicht gefunden werden, da die Datei nicht gefunden werden kann.
In diesem Fall müssen Sie das try / catch-Konstrukt verwenden, um den ursprünglichen Fehler abzufangen. Dann müssen Sie das 
createError mit 
createError neu 
createError :
 app.get('/testing', asyncHandler(async (req, res, next) => {  try {    const { file } = req.body    const contents = await readFilePromise(path.join(__dirname, file))  } catch (error) {    throw createError(400, `File ${file} does not exist`)  } }) 
▍ 404 Fehlerbehandlung
Wenn die Anforderung alle Intermediate-Handler und -Routen durchlaufen hat, aber nicht verarbeitet wurde, bedeutet dies, dass der einer solchen Anforderung entsprechende Endpunkt nicht gefunden wurde.
Um 
404 Not Found Fehler zu behandeln, müssen Sie zwischen den Routen und der Fehlerbehandlungsroutine eine zusätzliche Behandlungsroutine hinzufügen. So sieht die Erstellung des 404-Fehlerobjekts aus:
 
Fehlerdetails▍ ERR_HTTP_HEADERS_SENT Fehlerhinweise
Keine Panik, wenn die Fehlermeldung 
ERR_HTTP_HEADERS_SENT: Cannot set headers after they are sent to the client . Es entsteht, weil im selben Handler die Methode, die die Antwortheader setzt, wiederholt aufgerufen wird. Mit den folgenden Methoden werden die Antwortheader automatisch festgelegt:
- res.send
- res.json
- res.render
- res.sendFile
- res.sendStatus
- res.end
- res.redirect
Wenn Sie 
res.json res.render und 
res.json im selben 
res.render res.json , wird der Fehler 
ERR_HTTP_HEADERS_SENT :
 app.get('/testing', (req, res) => {  res.render('new-page')  res.json({ message: '¯\_(ツ)_/¯' }) }) 
Wenn dieser Fehler auftritt, überprüfen Sie den Code des Antworthandlers sorgfältig und stellen Sie sicher, dass es keine Situationen gibt, in denen mehrere der oben beschriebenen Methoden aufgerufen werden.
▍ Fehlerbehandlung und Datenstreaming
Wenn beim Streamen der Antwort auf das Frontend ein Fehler 
ERR_HTTP_HEADERS_SENT , tritt möglicherweise derselbe 
ERR_HTTP_HEADERS_SENT Fehler auf.
In diesem Fall muss die Fehlerbehandlung an Standardhandler übergeben werden. Ein solcher Handler sendet einen Fehler und beendet die Verbindung automatisch.
 app.use((error, req, res, next) => {   
Zusammenfassung
Heute habe ich Ihnen alles gesagt, was ich über die Fehlerbehandlung in Express weiß. Ich hoffe, dies hilft Ihnen beim Schreiben zuverlässigerer Express-Anwendungen.
Sehr geehrte Leser! Wie gehen Sie mit Fehlern in Ihren Node.js-Projekten um?
