Start · Sprachen · JavaScript · Referenz · Error.prototype.toString()

Error.prototype.toString()

Methode

Gibt einen String zurück, der den Fehler darstellt – üblicherweise im Format <code>"name: message"</code>, z. B. <code>"TypeError: x is not a function"</code>.

seit JavaScript ES1 (Baseline: alle Browser, Node.js) Kategorie: method-property

Signatur

Error.prototype.toString()

Beschreibung

Error.prototype.toString() baut aus den Eigenschaften name und message eines Fehlerobjekts einen gut lesbaren String. Alle eingebauten Fehlertypen (TypeError, RangeError, SyntaxError …) und eigene Klassen, die von Error erben, nutzen diese Methode. JavaScript ruft sie automatisch auf, wenn ein Fehler in einen String umgewandelt wird, etwa bei der Verkettung mit +, in Template-Literalen oder mit String(err).

Der Algorithmus ist genau festgelegt:

  • Ist this kein Objekt, wird ein TypeError geworfen.
  • name wird gelesen. Ist der Wert undefined, wird "Error" verwendet, sonst der in einen String umgewandelte Wert.
  • message wird gelesen. Ist der Wert undefined, wird "" verwendet, sonst der in einen String umgewandelte Wert.
  • Ist name leer, wird nur message zurückgegeben. Ist message leer, nur name. Sonst lautet das Ergebnis name + ": " + message.

In der Praxis nutzt man die Methode für kurze, einzeilige Fehlermeldungen: in Logdateien, in UI-Hinweisen oder bei der Serialisierung, wenn der vollständige Stacktrace nicht gebraucht wird. Wichtig ist, bei eigenen Fehlerklassen name richtig zu setzen. Sonst steht in der Ausgabe nur das allgemeine "Error".

Rückgabewert

Typ
string
Beschreibung
Eine String-Darstellung des Fehlers: "name: message", nur name (wenn message leer ist) oder nur message (wenn name leer ist).

Beispiele

Standardfall: eingebaute Fehlertypen

const e1 = new Error('Datei nicht gefunden');
const e2 = new RangeError('Wert muss zwischen 1 und 10 liegen');

console.log(e1.toString());
console.log(e2.toString());

// Auch Fehler, die die Laufzeitumgebung selbst wirft
try {
  null.foo;
} catch (err) {
  console.log(err.toString());
}
Error: Datei nicht gefunden RangeError: Wert muss zwischen 1 und 10 liegen TypeError: Cannot read properties of null (reading 'foo')

Eigene Fehlerklasse mit sprechendem Namen

class ValidationError extends Error {
  constructor(field, message) {
    super(message);
    this.name = 'ValidationError'; // sonst stünde dort nur "Error"
    this.field = field;
  }
}

const validateEmail = (email) => {
  if (!email.includes('@')) {
    throw new ValidationError('email', `Ungültige E-Mail-Adresse: ${email}`);
  }
  return true;
};

try {
  validateEmail('max.mustermann');
} catch (err) {
  // Implizite Umwandlung per Template-Literal ruft toString() auf
  console.log(`[${new Date().toISOString().slice(0, 10)}] ${err}`);
}
[2024-05-01] ValidationError: Ungültige E-Mail-Adresse: max.mustermann

Randfälle: leere Werte und fremde Objekte

const leer = new TypeError();
console.log(leer.toString()); // message ist ""

const ohneName = new Error('Nur die Nachricht');
ohneName.name = '';
console.log(ohneName.toString());

const undefName = new Error('Hallo');
undefName.name = undefined;
console.log(undefName.toString()); // fällt auf "Error" zurück

// Funktioniert generisch mit jedem Objekt
console.log(Error.prototype.toString.call({ name: 'HttpError', message: '404' }));

// Primitive Werte als this führen zu einem TypeError
try {
  Error.prototype.toString.call('kein Objekt');
} catch (err) {
  console.log(err.name);
}
TypeError Nur die Nachricht Error: Hallo HttpError: 404 TypeError

Nutzerfreundliche Meldung vs. vollständiger Stacktrace

const ladeDaten = async (url) => {
  try {
    const res = await fetch(url);
    if (!res.ok) throw new Error(`HTTP ${res.status}`, { cause: res.statusText });
    return await res.json();
  } catch (err) {
    // Kurz für die Oberfläche
    const kurz = String(err);
    // Ausführlich für das Entwickler-Log
    console.error(err.stack);
    return { fehler: kurz };
  }
};

ladeDaten('https://example.com/gibt-es-nicht').then(console.log);
{ fehler: 'Error: HTTP 404' }

// Wichtig · Fallstricke

  • Kein Stacktrace, kein cause: toString() liefert nur name und message. Für die Fehlersuche ist meist err.stack (nicht standardisiert, aber überall verfügbar) oder console.error(err) besser geeignet. Die Eigenschaft cause und die Liste errors eines AggregateError fehlen in der Ausgabe.
  • console.log(err) ≠ err.toString(): Browser und Node.js zeigen beim Loggen des Objekts meist den Stack und weitere Eigenschaften an. Die Ausgabe von toString() ist nur eine einzelne Zeile.
  • name vergessen: Bei eigenen Unterklassen ohne this.name = '…' erscheint das geerbte "Error". Eine Alternative ist this.name = this.constructor.name. Vorsicht: Minifier können Klassennamen verändern.
  • JSON.stringify(err) liefert "{}": name, message und stack sind nicht aufzählbar. Zum Serialisieren eignet sich toString() oder ein eigenes Objekt wie { name, message }.
  • Sicherheit: Fehlermeldungen können Nutzereingaben enthalten. Gib das Ergebnis im DOM nur per textContent aus, nicht per innerHTML, sonst droht XSS. Zeige Endnutzern außerdem keine internen Details wie Pfade oder SQL.
  • Die Methode ist generisch: Mit call funktioniert sie für jedes Objekt, das name und message hat. Wird sie mit einem primitiven Wert als this aufgerufen, wirft sie einen TypeError.