Start · Sprachen · JavaScript · Referenz · SuppressedError: error

SuppressedError: error

Eigenschaft

Die Eigenschaft <code>error</code> einer <code>SuppressedError</code>-Instanz enthält den später aufgetretenen Fehler, durch den ein früherer Fehler (<code>suppressed</code>) verdrängt wurde.

seit JavaScript ES2026 (Explicit Resource Management) – Chrome 134 Kategorie: method-property

Signatur

suppressedError.error

Beschreibung

Ein SuppressedError entsteht, wenn während der Behandlung eines Fehlers ein zweiter Fehler auftritt. Typisch ist das beim Aufräumen von Ressourcen mit using, await using, DisposableStack oder AsyncDisposableStack: Wenn der Block einen Fehler wirft und danach auch [Symbol.dispose]() fehlschlägt, bündelt JavaScript beide Fehler in einem SuppressedError. So geht keiner der beiden verloren.

Die Eigenschaft error enthält den neueren Fehler, also den, der die Unterdrückung ausgelöst hat (zum Beispiel den Fehler beim Aufräumen). Der ältere, verdrängte Fehler steht in suppressed. Wer den eigentlichen Grund für das Scheitern sucht, findet ihn deshalb oft in suppressed. Der Fehler beim Aufräumen steht dagegen in error.

error ist eine eigene Dateneigenschaft der Instanz und liegt nicht auf dem Prototyp. Sie ist beschreibbar (writable) und konfigurierbar (configurable), aber nicht aufzählbar (enumerable: false). Ihr Wert ist das erste Argument, das an den Konstruktor new SuppressedError(error, suppressed, message) übergeben wurde. Er kann einen beliebigen Typ haben, denn in JavaScript lässt sich jeder Wert werfen.

Rückgabewert

Typ
any
Beschreibung
Der Wert, der beim Erzeugen als error übergeben wurde. Meist ist das eine Error-Instanz, es kann aber jeder beliebige geworfene Wert sein, auch undefined.

Beispiele

Direkte Instanziierung und Zugriff

const aufraeumFehler = new Error('Datei konnte nicht geschlossen werden');
const ursprung = new TypeError('Ungültige Eingabe');

const err = new SuppressedError(aufraeumFehler, ursprung, 'Fehler beim Aufräumen');

console.log(err.error.message);      // neuerer Fehler
console.log(err.suppressed.message); // verdrängter Fehler
console.log(Object.keys(err));       // nicht aufzählbar
Datei konnte nicht geschlossen werden Ungültige Eingabe []

Fehler in using-Block und in Symbol.dispose

const oeffneVerbindung = (name) => ({
  name,
  [Symbol.dispose]() {
    throw new Error(`Schließen von ${name} fehlgeschlagen`);
  }
});

try {
  using conn = oeffneVerbindung('db');
  throw new Error('Abfrage fehlgeschlagen');
} catch (e) {
  if (e instanceof SuppressedError) {
    console.log('Aufräumen:', e.error.message);
    console.log('Ursache:', e.suppressed.message);
  }
}
Aufräumen: Schließen von db fehlgeschlagen Ursache: Abfrage fehlgeschlagen

Verschachtelte SuppressedErrors mit DisposableStack auflösen

const stack = new DisposableStack();
stack.defer(() => { throw new Error('Cleanup A'); });
stack.defer(() => { throw new Error('Cleanup B'); });

// Alle Fehler einer Kette einsammeln
const sammleFehler = (e) =>
  e instanceof SuppressedError
    ? [e.error, ...sammleFehler(e.suppressed)]
    : [e];

try {
  stack.dispose(); // LIFO: erst B, dann A
} catch (e) {
  console.log(sammleFehler(e).map((f) => f.message));
}
[ 'Cleanup A', 'Cleanup B' ]

// Wichtig · Fallstricke

  • Reihenfolge nicht verwechseln: error ist der neuere Fehler, der unterdrückt hat, und suppressed der ältere, verdrängte. Die eigentliche Ursache aus dem Block steht deshalb häufig in suppressed.
  • Verschachtelung: Schlagen mehrere Aufräumschritte fehl, entstehen verschachtelte SuppressedError-Objekte. Dann kann suppressed selbst wieder ein SuppressedError sein. Um alle Fehler zu erfassen, muss man die Kette rekursiv durchlaufen.
  • Beliebiger Typ: error muss keine Error-Instanz sein. Prüfe den Typ, bevor du auf .message oder .stack zugreifst.
  • Nicht aufzählbar: JSON.stringify(err) und Object.keys(err) enthalten error nicht. Für Logging solltest du die Eigenschaft ausdrücklich auslesen.
  • Kompatibilität: SuppressedError gehört zu Explicit Resource Management und ist noch recht neu. In Safari und älteren Laufzeitumgebungen fehlt es. Vorher mit typeof SuppressedError !== 'undefined' prüfen oder ein Polyfill wie core-js verwenden. TypeScript unterstützt es ab Version 5.2 mit lib: ["esnext.disposable"].