Start · Sprachen · JavaScript · Referenz · Error: cause

Error: cause

Eigenschaft

Die Eigenschaft <code>cause</code> einer <code>Error</code>-Instanz enthält die ursprüngliche Ursache eines Fehlers, meist einen anderen, abgefangenen Fehler.

seit JavaScript ES2022 Kategorie: method-property

Signatur

Error.prototype.cause (Instanz-Eigenschaft: error.cause)

Beschreibung

Die Eigenschaft cause gibt an, welcher ursprüngliche Fehler zu einem neuen Fehler geführt hat. Man setzt sie über das Optionsobjekt des Konstruktors: new Error(message, { cause }). So lassen sich Fehlerketten bauen. Ein Low-Level-Fehler wie ein Netzwerk- oder Parse-Fehler wird in einen aussagekräftigeren, fachlichen Fehler verpackt, ohne dass die technische Ursache samt Stacktrace verloren geht.

cause ist eine eigene Dateneigenschaft der Instanz, keine Eigenschaft von Error.prototype. Sie wird nur angelegt, wenn das Optionsobjekt tatsächlich einen Schlüssel cause hat. Die Eigenschaft ist beschreibbar und konfigurierbar, aber nicht aufzählbar. Deshalb erscheint sie weder in Object.keys() noch in JSON.stringify().

Der Wert kann beliebigen Typs sein: ein anderes Error-Objekt, ein String oder ein Objekt mit strukturierten Zusatzdaten. Üblich und empfohlen ist ein Error-Objekt. Die Option funktioniert bei allen eingebauten Fehlerklassen (TypeError, RangeError, AggregateError usw.) und bei eigenen Unterklassen, die die Optionen an super() weitergeben.

Parameter

Name Typ Default Beschreibung
$options.cause any Wird im Konstruktor als zweites (bei AggregateError als drittes) Argument im Optionsobjekt übergeben. Der Wert landet unverändert in error.cause.

Rückgabewert

Typ
any
Beschreibung
Die ursprüngliche Ursache, so wie sie im Konstruktor übergeben wurde. Wurde kein cause angegeben, existiert die Eigenschaft nicht und der Zugriff liefert undefined.

Beispiele

Low-Level-Fehler in fachlichen Fehler verpacken

const loadConfig = (json) => {
  try {
    return JSON.parse(json);
  } catch (err) {
    throw new Error('Konfiguration konnte nicht geladen werden', { cause: err });
  }
};

try {
  loadConfig('{ ungültig }');
} catch (err) {
  console.log(err.message);
  console.log(err.cause instanceof SyntaxError);
}
Konfiguration konnte nicht geladen werden true

Fehlerkette bei fetch mit async/await

const fetchUser = async (id) => {
  try {
    const res = await fetch(`https://api.example.com/users/${id}`);
    if (!res.ok) {
      throw new Error(`HTTP ${res.status}`);
    }
    return await res.json();
  } catch (err) {
    throw new Error(`Benutzer ${id} nicht abrufbar`, { cause: err });
  }
};

fetchUser(42).catch((err) => {
  // Gesamte Ursachenkette ausgeben
  let current = err;
  while (current) {
    console.log('→', current.message ?? current);
    current = current.cause;
  }
});
→ Benutzer 42 nicht abrufbar → HTTP 404

Strukturierte Ursache und eigene Fehlerklasse

class ValidationError extends Error {
  constructor(message, options) {
    super(message, options); // options mit cause weiterreichen
    this.name = 'ValidationError';
  }
}

const err = new ValidationError('Ungültige Eingabe', {
  cause: { field: 'email', value: 'foo@' }
});

console.log(err.cause.field);
console.log(Object.keys(err));
console.log(Object.hasOwn(err, 'cause'));
email [] true

Fehlende vs. explizit undefinierte Ursache

const a = new Error('ohne');
const b = new Error('mit', { cause: undefined });

console.log('cause' in a);
console.log('cause' in b);
false true

// Wichtig · Fallstricke

  • Kompatibilität: Seit ES2022. Unterstützt ab Chrome 93, Firefox 91, Safari 15 und Node.js 16.9. In älteren Umgebungen wird das Optionsobjekt stillschweigend ignoriert, und cause bleibt dann undefined.
  • Nicht aufzählbar: JSON.stringify(err) enthält cause nicht, message und stack übrigens auch nicht. Für Logging oder Serialisierung muss man die Ursachenkette selbst ablaufen.
  • Eigene Unterklassen: Das zweite Argument muss an super(message, options) weitergereicht werden, sonst geht cause verloren.
  • Bei AggregateError steht das Optionsobjekt an dritter Stelle: new AggregateError(errors, message, { cause }).
  • Node.js und moderne Browser-DevTools zeigen die Ursachenkette in der Konsole meist automatisch an. Eigene Logger tun das oft nicht.
  • Achtung bei Zyklen: Wenn sich eine Ursachenkette selbst referenziert, laufen rekursive Ausgabefunktionen endlos. Eine Tiefenbegrenzung ist sinnvoll.
  • Sicherheit: Ursachen enthalten oft interne Details wie SQL, Pfade oder Tokens. Solche Details nicht ungefiltert an Clients ausliefern.