Fehlerbehandlung

Die error.js-Dateikonvention ermöglicht die elegante Behandlung unerwarteter Laufzeitfehler in verschachtelten Routen.

  • Automatisches Umschließen eines Routensegments und seiner verschachtelten Kindelemente in einer React Error Boundary.
  • Erstellen von spezifischen Fehler-UIs für bestimmte Segmente mithilfe der Dateisystemhierarchie zur Feinjustierung.
  • Isolierung von Fehlern auf betroffene Segmente bei gleichzeitiger Funktionsfähigkeit des restlichen Anwendung.
  • Hinzufügen von Funktionen zur Fehlerbehebung ohne vollständigen Seitenneulade.

Erstellen Sie eine Fehler-UI, indem Sie eine error.js-Datei in einem Routensegment anlegen und eine React-Komponente exportieren:

error.js special file
'use client' // Fehlerkomponenten müssen Client Components sein

import { useEffect } from 'react'

export default function Error({
  error,
  reset,
}: {
  error: Error & { digest?: string }
  reset: () => void
}) {
  useEffect(() => {
    // Fehler an einen Fehlerreporting-Service senden
    console.error(error)
  }, [error])

  return (
    <div>
      <h2>Etwas ist schiefgelaufen!</h2>
      <button
        onClick={
          // Versuch der Wiederherstellung durch erneutes Rendern des Segments
          () => reset()
        }
      >
        Erneut versuchen
      </button>
    </div>
  )
}
'use client' // Fehlerkomponenten müssen Client Components sein

import { useEffect } from 'react'

export default function Error({ error, reset }) {
  useEffect(() => {
    // Fehler an einen Fehlerreporting-Service senden
    console.error(error)
  }, [error])

  return (
    <div>
      <h2>Etwas ist schiefgelaufen!</h2>
      <button
        onClick={
          // Versuch der Wiederherstellung durch erneutes Rendern des Segments
          () => reset()
        }
      >
        Erneut versuchen
      </button>
    </div>
  )
}

Funktionsweise von error.js

How error.js works
  • error.js erstellt automatisch eine React Error Boundary, die ein verschachteltes Kindsegment oder eine page.js-Komponente umschließt.
  • Die aus error.js exportierte React-Komponente wird als Fallback-Komponente verwendet.
  • Wenn innerhalb der Error Boundary ein Fehler auftritt, wird der Fehler eingedämmt und die Fallback-Komponente gerendert.
  • Während die Fallback-Fehlerkomponente aktiv ist, behalten Layouts oberhalb der Error Boundary ihren Zustand bei und bleiben interaktiv, und die Fehlerkomponente kann Funktionen zur Fehlerbehebung anzeigen.

Fehlerbehebung

Die Ursache eines Fehlers kann manchmal temporär sein. In diesen Fällen kann ein einfacher Neustart das Problem lösen.

Eine Fehlerkomponente kann die reset()-Funktion verwenden, um den Benutzer zur Fehlerbehebung aufzufordern. Bei Ausführung versucht die Funktion, den Inhalt der Error Boundary erneut zu rendern. Bei Erfolg wird die Fallback-Fehlerkomponente durch das Ergebnis des erneuten Renderings ersetzt.

'use client'

export default function Error({
  error,
  reset,
}: {
  error: Error & { digest?: string }
  reset: () => void
}) {
  return (
    <div>
      <h2>Etwas ist schiefgelaufen!</h2>
      <button onClick={() => reset()}>Erneut versuchen</button>
    </div>
  )
}
'use client'

export default function Error({ error, reset }) {
  return (
    <div>
      <h2>Etwas ist schiefgelaufen!</h2>
      <button onClick={() => reset()}>Erneut versuchen</button>
    </div>
  )
}

Verschachtelte Routen

React-Komponenten, die durch spezielle Dateien erstellt werden, werden in einer spezifischen verschachtelten Hierarchie gerendert.

Beispielsweise wird eine verschachtelte Route mit zwei Segmenten, die beide layout.js- und error.js-Dateien enthalten, in der folgenden vereinfachten Komponentenhierarchie gerendert:

Nested Error Component Hierarchy

Die verschachtelte Komponentenhierarchie hat Auswirkungen auf das Verhalten von error.js-Dateien in einer verschachtelten Route:

  • Fehler steigen zur nächstgelegenen übergeordneten Error Boundary auf. Das bedeutet, dass eine error.js-Datei Fehler für alle ihre verschachtelten Kindsegmente behandelt. Feinere oder gröbere Fehler-UIs können durch Platzieren von error.js-Dateien auf verschiedenen Ebenen in den verschachtelten Ordnern einer Route erreicht werden.
  • Eine error.js-Boundary wird keine Fehler behandeln, die in einer layout.js-Komponente im selben Segment auftreten, da die Error Boundary innerhalb dieser Layout-Komponente verschachtelt ist.

Fehlerbehandlung in Layouts

error.js-Boundaries fangen keine Fehler ab, die in layout.js- oder template.js-Komponenten des selben Segments auftreten. Diese intentionale Hierarchie stellt sicher, dass wichtige UI-Elemente, die zwischen Geschwisterrouten geteilt werden (wie Navigation), bei einem Fehler sichtbar und funktionsfähig bleiben.

Um Fehler innerhalb eines bestimmten Layouts oder Templates zu behandeln, platzieren Sie eine error.js-Datei im übergeordneten Segment des Layouts.

Um Fehler im Root-Layout oder -Template zu behandeln, verwenden Sie eine Variante von error.js namens global-error.js.

Fehlerbehandlung in Root-Layouts

Die Root-app/error.js-Boundary fängt keine Fehler ab, die in der Root-app/layout.js- oder app/template.js-Komponente auftreten.

Um speziell Fehler in diesen Root-Komponenten zu behandeln, verwenden Sie eine Variante von error.js namens app/global-error.js im Root-app-Verzeichnis.

Im Gegensatz zur Root-error.js umschließt die global-error.js-Boundary die gesamte Anwendung, und ihre Fallback-Komponente ersetzt das Root-Layout, wenn sie aktiv ist. Daher ist es wichtig zu beachten, dass global-error.js eigene <html>- und <body>-Tags definieren muss.

global-error.js ist die am wenigsten granulare Fehler-UI und kann als "Allesfänger"-Fehlerbehandlung für die gesamte Anwendung betrachtet werden. Sie wird wahrscheinlich selten ausgelöst, da Root-Komponenten typischerweise weniger dynamisch sind und andere error.js-Boundaries die meisten Fehler abfangen.

Auch wenn eine global-error.js definiert ist, wird dennoch empfohlen, eine Root-error.js zu definieren, deren Fallback-Komponente innerhalb des Root-Layouts gerendert wird, das global geteilte UI und Branding enthält.

'use client'

export default function GlobalError({
  error,
  reset,
}: {
  error: Error & { digest?: string }
  reset: () => void
}) {
  return (
    <html>
      <body>
        <h2>Etwas ist schiefgelaufen!</h2>
        <button onClick={() => reset()}>Erneut versuchen</button>
      </body>
    </html>
  )
}
'use client'

export default function GlobalError({ error, reset }) {
  return (
    <html>
      <body>
        <h2>Etwas ist schiefgelaufen!</h2>
        <button onClick={() => reset()}>Erneut versuchen</button>
      </body>
    </html>
  )
}

Gut zu wissen:

  • global-error.js ist nur in der Produktion aktiviert. In der Entwicklung wird stattdessen unser Error Overlay angezeigt.

Behandlung von Server-Fehlern

Wenn ein Fehler in einer Server Component auftritt, leitet Next.js ein Error-Objekt (in der Produktion von sensiblen Fehlerinformationen bereinigt) an die nächstgelegene error.js-Datei als error-Prop weiter.

Schutz sensibler Fehlerinformationen

Während der Produktion enthält das an den Client weitergeleitete Error-Objekt nur eine generische message- und digest-Eigenschaft.

Dies ist eine Sicherheitsvorkehrung, um das versehentliche Offenlegen potenziell sensibler Details im Fehler an den Client zu vermeiden.

Die message-Eigenschaft enthält eine generische Nachricht über den Fehler, und die digest-Eigenschaft enthält einen automatisch generierten Hash des Fehlers, der zum Abgleich mit dem entsprechenden Fehler in serverseitigen Logs verwendet werden kann.

Während der Entwicklung wird das an den Client weitergeleitete Error-Objekt serialisiert und enthält die message des ursprünglichen Fehlers zur einfacheren Fehlersuche.