Start · Sprachen · JavaScript · Referenz · Error.captureStackTrace()

Error.captureStackTrace()

Methode

Legt auf einem beliebigen Objekt eine <code>stack</code>-Eigenschaft mit dem aktuellen Stack-Trace an und kann dabei Frames oberhalb einer Funktion ausblenden.

seit JavaScript V8 (Chrome, Node.js) seit jeher; Firefox 121+, Saf Kategorie: method-property

Signatur

Error.captureStackTrace(targetObject, constructorOpt)

Beschreibung

Error.captureStackTrace() ist eine statische Methode, die den aktuellen Aufruf-Stack erfasst und als stack-Eigenschaft auf dem übergebenen Objekt ablegt. Das Zielobjekt muss dafür keine Error-Instanz sein. Jedes beliebige Objekt bekommt damit einen Stack-Trace im gleichen Format wie new Error().stack.

Wirklich nützlich wird die Methode durch den optionalen zweiten Parameter constructorOpt. Übergibt man eine Funktion, werden alle Frames oberhalb dieser Funktion aus dem Trace entfernt, der Aufruf der Funktion selbst eingeschlossen. So tauchen interne Details wie Konstruktoren eigener Fehlerklassen, Hilfsfunktionen oder Assertion-Wrapper nicht im Stack-Trace auf. Wer die Fehlermeldung liest, sieht sofort die Stelle im eigenen Code, an der das Problem entstanden ist.

Typische Einsatzfälle:

  • eigene Fehlerklassen (class ValidationError extends Error), deren Konstruktor nicht im Trace stehen soll
  • Assertion- und Test-Bibliotheken, deren interne Funktionen ausgeblendet werden sollen
  • Stack-Traces an Objekten, die keine Fehler sind, zum Beispiel zum Debuggen von Ressourcen-Lecks („Wo wurde diese Verbindung geöffnet?“)

Die Methode stammt aus der JavaScript-Engine V8 und ist kein Bestandteil des ECMAScript-Standards. Mittlerweile unterstützen sie aber alle großen Engines.

Parameter

Name Typ Default Beschreibung
$targetObject Pflicht object Das Objekt, auf dem die Eigenschaft stack angelegt wird. Es kann ein beliebiges Objekt sein, auch eines, das kein Error ist.
$constructorOpt Function undefined Optionale Funktion. Alle Stack-Frames oberhalb des obersten Aufrufs dieser Funktion werden aus dem Trace entfernt, der Aufruf selbst eingeschlossen. Taucht die Funktion nicht im Stack auf, bleibt der Trace leer (nur die Kopfzeile).

Rückgabewert

Typ
void
Beschreibung
Gibt undefined zurück. Die Methode verändert das Zielobjekt direkt, indem sie die Eigenschaft stack darauf anlegt.

Beispiele

Stack-Trace an einem beliebigen Objekt

const obj = { message: 'Hier wurde etwas erzeugt' };
Error.captureStackTrace(obj);

// Die erste Zeile stammt aus toString() des Objekts
console.log(obj.stack.split('\n')[0]);
[object Object]

Eigene Fehlerklasse ohne Konstruktor im Trace

class ValidationError extends Error {
  constructor(field, message) {
    super(message);
    this.name = 'ValidationError';
    this.field = field;
    // Konstruktor-Frame ausblenden, falls verfügbar
    if (typeof Error.captureStackTrace === 'function') {
      Error.captureStackTrace(this, ValidationError);
    }
  }
}

const validateUser = (user) => {
  if (!user.email) throw new ValidationError('email', 'E-Mail fehlt');
};

try {
  validateUser({ name: 'Anna' });
} catch (err) {
  console.log(err.stack.split('\n').slice(0, 2).join('\n'));
}
ValidationError: E-Mail fehlt at validateUser (file.js:14:31)

Assertion-Helfer, der sich selbst ausblendet

function assert(condition, message = 'Assertion fehlgeschlagen') {
  if (!condition) {
    const err = new Error(message);
    // Frame von assert() entfernen: Trace beginnt beim Aufrufer
    Error.captureStackTrace(err, assert);
    throw err;
  }
}

const divide = (a, b) => {
  assert(b !== 0, 'Division durch 0');
  return a / b;
};

try {
  divide(10, 0);
} catch (e) {
  console.log(e.stack.split('\n')[1].trim().startsWith('at divide'));
}
true

Herkunft offener Ressourcen verfolgen

const openHandles = new Set();

const openConnection = (name) => {
  const handle = { name };
  // Merken, wo die Verbindung geöffnet wurde
  Error.captureStackTrace(handle, openConnection);
  openHandles.add(handle);
  return handle;
};

const closeConnection = (handle) => openHandles.delete(handle);

const db = openConnection('db');
openConnection('cache'); // wird nie geschlossen
closeConnection(db);

for (const h of openHandles) {
  console.log(`Nicht geschlossen: ${h.name}`);
  console.log(h.stack.split('\n')[1].trim());
}
Nicht geschlossen: cache at file.js:14:1

// Wichtig · Fallstricke

  • Nicht standardisiert: Die Methode stammt aus V8. Chrome, Edge und Node.js unterstützen sie schon lange, Firefox erst ab Version 121, Safari/JavaScriptCore ebenfalls. In Code, der in vielen Umgebungen laufen muss, vorher mit typeof Error.captureStackTrace === 'function' prüfen.
  • Format von stack: Der Inhalt ist nicht standardisiert. Die Formate von V8, SpiderMonkey und JavaScriptCore unterscheiden sich. Die Zeilen also nicht fest parsen, sondern nur für Diagnose und Logging verwenden.
  • Kopfzeile: Die erste Zeile des Traces entsteht über targetObject.toString() bzw. name/message. Bei einfachen Objekten steht dort deshalb [object Object].
  • Lazy-Formatierung in V8: V8 formatiert den Stack erst beim ersten Zugriff auf stack. Das Ergebnis hängt von Error.prepareStackTrace ab, und die Anzahl der Frames begrenzt Error.stackTraceLimit (Standard: 10).
  • constructorOpt nicht im Stack: Kommt die übergebene Funktion im aktuellen Stack nicht vor, bleiben keine Frames übrig.
  • Performance: Einen Stack-Trace zu erfassen kostet Zeit. Die Methode daher nicht in heißen Schleifen für jedes Objekt aufrufen (etwa beim Leak-Tracking nur im Debug-Modus).
  • Sicherheit: Stack-Traces verraten Dateipfade und interne Struktur. Sie gehören nicht ungefiltert in HTTP-Antworten an Clients.
  • Bei class … extends Error ist der Aufruf in modernen Engines oft unnötig, weil der Konstruktor ohnehin kaum stört. Er lohnt sich vor allem bei Factory-Funktionen und Helfern.