12k
All articles

JavaScript's Error.isError() erklärt

Error.isError() erkennt echte JavaScript-Fehler realmsübergreifend, erklärt, warum es instanceof Error schlägt, und zeigt einen sicheren Fallback.

OpenReplay Team
OpenReplay Team
JavaScript's Error.isError() erklärt

Error.isError(value) ist eine statische Methode, die nur dann true zurückgibt, wenn value ein echtes Error-Objekt ist. Sie bleibt selbst über Realm-Grenzen hinweg zuverlässig, weil sie ein internes Kennzeichen ([[ErrorData]]) prüft, anstatt die Prototypenkette abzulaufen.

Wenn Sie jemals Ihren Error-Tracker geöffnet und dort ein leeres {} gefunden haben, wo eigentlich eine echte Exception stehen sollte, dann kennen Sie das Problem, das diese Methode löst. Irgendwo dazwischen hat eine instanceof-Prüfung stillschweigend entschieden, dass Ihr Fehler kein Fehler ist. Die Methode wurde in ECMAScript 2026 standardisiert, womit die seit Langem bestehenden Schwächen von instanceof Error (Fehler aus iframes, die als Nicht-Fehler gelesen werden, und gefälschte Objekte, die als Fehler gelesen werden) nun eine erstklassige Lösung haben. Dieser Artikel erklärt, was die Methode tut, warum sie instanceof überlegen ist, welcher Mechanismus genau dahintersteckt, welche Sonderfälle es gibt und wie Sie sie mit einem sicheren Fallback einsetzen.

Das Verhalten ist genau so, wie man es erwarten würde: Error.isError(new Error()) ergibt true, und Error.isError({ message: 'x' }) ergibt false, denn die Methode prüft, wie das Objekt konstruiert wurde, und nicht bloß, wovon es erbt.

Die wichtigsten Erkenntnisse

  • Error.isError() führt eine gekennzeichnete Prüfung („branded check“) auf den internen Slot [[ErrorData]] durch – dieselbe Art nicht fälschbarer Prüfung, die Array.isArray() verwendet. Userland-Code kann sie also nicht umgehen.
  • instanceof Error versagt auf zwei entgegengesetzte Weisen: false für einen echten Fehler, der in einem anderen Realm erzeugt wurde, und true für ein gefälschtes Objekt, dessen Prototyp auf Error.prototype gesetzt wurde.
  • Die Methode gibt true zurück für eingebaute Unterklassen wie TypeError, für Klassen, die korrekt extend Error verwenden, und für DOMException in Browsern – wobei Safari derzeit false für DOMException zurückgibt.
  • Error.isError() ist Teil von ECMAScript 2026 und ist in Chrome/Edge 134+, Firefox 138+, Node.js 24.0.0+ sowie Safari 18.4 (teilweise) verfügbar.
  • Nutzen Sie sie an Grenzen (globale Handler, Logging-Anbindungen, Worker, iframes, SSR/Edge), wo ein stiller instanceof-Fehlschlag einen echten Fehler in Ihren Logs zu einem leeren Objekt macht.

Warum reicht instanceof Error nicht aus?

instanceof Error versagt auf zwei entgegengesetzte Weisen, und beide bleiben unbemerkt. Der TC39-Proposal beschreibt den ersten Fall genau: Ein echter Fehler, der eine Realm-Grenze überschritten hat – sei es aus einem iframe oder aus Nodes vm-Modul – kommt als False Negative zurück. Jeder Realm hat seinen eigenen Error-Konstruktor, daher ist ein in einem iframe erzeugter Fehler keine Instanz Ihres Error.

Der zweite Fehlschlag ist das Gegenteil: Jedes Objekt, das Error.prototype in seiner Kette hat, besteht die Prüfung, ohne ein echter Fehler zu sein. Hier beide Fehlschläge im Code:

// Failure 1 — cross-realm error reads as NOT an error
const iframe = document.createElement('iframe');
document.body.appendChild(iframe);
const crossRealmError = new iframe.contentWindow.Error('from iframe');

crossRealmError instanceof Error;   // → false  (wrong)
Error.isError(crossRealmError);     // → true   (correct)

// Failure 2 — fake object reads as an error
const fake = { message: "I'm not real" };
Object.setPrototypeOf(fake, Error.prototype);

fake instanceof Error;              // → true   (wrong)
Error.isError(fake);                // → false  (correct)

Beide Ergebnisse entsprechen dem dokumentierten Verhalten und sind kein Zufall. MDNs Referenz zur Methode stellt sie genau deshalb als robuste Alternative zu instanceof Error dar, weil sie beide Fehlermodi vermeidet: Ein geborgter Prototyp genügt nicht, um die Prüfung zu bestehen, und ein in einem anderen Realm erzeugter Fehler besteht sie dennoch. instanceof vergleicht die Konstruktor-Identität entlang der Prototypenkette und liegt daher in beiden Fällen falsch.

Eingabeinstanceof ErrorDuck-Typing ('message' in x)Error.isError()
Cross-Realm-Error (iframe/Worker/vm)false⚠️ hängt davon abtrue
Object.setPrototypeOf(obj, Error.prototype)true⚠️ truefalse
Instanz von class MyError extends Errortruetruetrue

Wie funktioniert Error.isError() intern?

Intern führt Error.isError() eine gekennzeichnete Prüfung auf einen internen Slot durch, anstatt die Prototypenkette zu untersuchen. MDN beschreibt den Mechanismus unmittelbar: Die Methode sucht nach einem privaten Feld, das der Error()-Konstruktor bei jedem von ihm erzeugten Fehler setzt. Das ist derselbe Trick, der hinter Array.isArray() steckt, und ein naher Verwandter dessen, wie der in-Operator auf eine Eigenschaft prüft.

Die Analogie zu Array.isArray() ist das mentale Modell, das man sich merken sollte. Array.isArray() akzeptiert ebenfalls Arrays, die in einem anderen Realm erzeugt wurden – dort, wo instanceof Array false meldet, weil jeder Realm einen separaten Array-Konstruktor besitzt. Error.isError() bringt dieselbe realm-sichere Kennzeichnung zu Fehlern.

Der Spezifikationstext auf Stage 4 benennt den Slot als [[ErrorData]] und hält die IsError-Operation bei drei Schritten: Alles, was kein Objekt ist, scheitert sofort, alles, was den Slot trägt, besteht, und alles Übrige scheitert. Der Slot wird bei der Konstruktion gesetzt und kann aus JavaScript heraus nicht gefälscht werden.

Warum ein Slot und nicht Object.prototype.toString? Weil Tag-Spoofing den alten Trick zunichtemachte. Der Autor des Proposals brachte das Problem ins Komitee: Sobald Symbol.toStringTag existierte, war eine Prüfung, die zuvor sowohl verlässlich als auch unfälschbar war, keines von beidem mehr. Und da außer Object#toString nie etwas den Error-Slot abfragte, blieb Userland-Code ohne jeden verlässlichen Test. Error.isError() schließt genau diese Lücke.

Wissenswerte Verhaltensdetails

Error.isError() gibt für die gesamte Error-Familie true und für alles andere false zurück, ohne eine Exception zu werfen. MDNs Beispiele zeigen, dass new Error(), new TypeError() und new DOMException() alle true ergeben, während ein Aufruf ohne Argument oder einer mit {}, null, undefined, 17 oder dem String "Error" false zurückgibt. Da das Spezifikations-Prädikat für jedes Nicht-Objekt und für Objekte ohne den Slot false liefert, werden Primitives und null saubersauber behandelt, statt einen Fehler auszulösen.

Korrekt erweiterte eigene Klassen werden erkannt, da sie das Kennzeichen erben:

class ValidationError extends Error {}
Error.isError(new ValidationError('bad input')); // → true

Abgelehnt werden nur Nachahmungen, die den Error-Konstruktor niemals aufrufen. Der Fall DOMException hat eine Feinheit, die man sich merken sollte. MDNs Regel lautet, dass DOMException-Instanzen die Prüfung bestehen. DOMException ist formal keine Unterklasse von Error, weil sein Konstruktor nicht vom Error-Konstruktor erbt, aber es trägt dasselbe Kennzeichen, sodass gekennzeichnete Prüfungen es dennoch als Fehler behandeln. Safari ist die Ausnahme: Chromes Monatsrückblick zum Release von Firefox 138 dokumentiert, dass Safari für DOMException false zurückgibt – weshalb die Methode noch keinen Baseline-Status erreicht hat, obwohl inzwischen alle großen Engines sie implementieren. MDN kennzeichnet sie aus demselben Grund weiterhin als „limited availability“. Behandeln Sie diesen einen Fall als noch nicht einheitlich.

Wann sollte man Error.isError() verwenden?

Nutzen Sie Error.isError() an Grenzen (globale Error-Handler, Logging- und Error-Reporting-Anbindungen, Test-Runner, Bibliotheken, SSR/Edge, Worker, iframes und Browser-Erweiterungen), wo ein stiller instanceof-Fehlschlag einen echten Fehler in Ihren Logs zu einem leeren {} macht. In eng begrenztem Code innerhalb desselben Realms ist einfaches instanceof völlig in Ordnung; der Nutzen liegt speziell an den Rändern, wo Werte Ausführungskontexte überschreiten.

Das entspricht einem realen Fehlerbild beim Reporting: Eine instanceof-Prüfung an einer Grenze klassifiziert einen echten geworfenen Fehler als einfaches Objekt um, sodass er ohne Message und ohne Stack in Ihrer Pipeline landet. Session Replay ist hier eine nützliche Technik: Das Nachspielen der Session zeigt den Konsolenfehler, der tatsächlich geworfen wurde, und legt damit die Diskrepanz zwischen dem, was der Browser gesehen hat, und dem, was Ihr Anbindungscode gemeldet hat, offen. Die Lösung besteht darin, an diesen Grenzen mit Error.isError() eine gekennzeichnete Prüfung durchzuführen, bevor irgendetwas serialisiert oder geloggt wird.

Browser- und Runtime-Unterstützung sowie ein sicherer Fallback

Error.isError() ist Teil von ECMAScript 2026, der 17. Edition, die Ecma International am 30. Juni 2026 ratifiziert hat; der Proposal erreichte Stage 4 beim TC39-Meeting im Mai 2025. In Browsern funktioniert es ab Chrome und Edge 134, Safari 18.4 und Firefox 138, das am 29. April 2025 veröffentlicht wurde. Auf Serverseite hat Node.js 24.0.0 es über das Upgrade auf V8 13.6 übernommen, das es zusammen mit Float16Array, Explicit Resource Management, RegExp.escape und WebAssembly Memory64 gebracht hat.

Für ein Drop-in-Upgrade, das auf älteren Zielumgebungen sauber degradiert, empfiehlt sich Feature Detection:

function isError(value) {
  return typeof Error.isError === 'function'
    ? Error.isError(value)      // realm-safe on modern engines
    : value instanceof Error;   // fallback, not realm-safe
}

In TypeScript fungiert Error.isError(e) zudem als Type Guard und verengt einen als unknown gefangenen Wert innerhalb des if-Zweigs auf Error, sodass e.message ohne manuellen Cast typsicher ist.

Fazit

Error.isError() schließt eine Lücke, die Duck-Typing und instanceof nie schließen konnten: Es fragt, ob die Engine einen Wert tatsächlich als Fehler gekennzeichnet hat, sodass sowohl Cross-Realm-Fehler als auch prototypengefälschte Nachahmungen korrekt aufgelöst werden. Stellen Sie Ihre Prüfungen an den Grenzen (Logging-Anbindung, globale Handler, Worker- und iframe-Nahtstellen) noch heute auf den Wrapper mit Feature Detection um, und behalten Sie instanceof nur dort, wo der Code seinen eigenen Realm nie verlässt.

FAQs

Ist Error.isError() standardisiert oder noch ein experimenteller Proposal?

Error.isError() ist vollständig standardisiert. Es erreichte beim 108. Meeting im Mai 2025 Stage 4 des TC39-Prozesses und ist in ECMAScript 2026, der 17. Edition der Sprachspezifikation, enthalten. Es ist kein Proposal und kein experimentelles Feature mehr, weshalb Beschreibungen, die es als 'noch nicht standardisiert' oder 'Stage 3' bezeichnen, veraltet sind. Betrachten Sie es als ausgeliefertes Sprachfeature.

Funktioniert Error.isError() mit eigenen Error-Klassen?

Ja, solange die Klasse Error korrekt erweitert. Eine Klasse, die als 'class MyError extends Error {}' definiert ist, erbt das interne Kennzeichen, das der Error-Konstruktor setzt, sodass Error.isError(new MyError()) true zurückgibt. Abgelehnt werden nur nachgeahmte Objekte, die den Error-Konstruktor nie aufrufen, etwa ein einfaches Objekt, dem Error.prototype in die Kette gezwungen wurde. Voraussetzung ist korrektes Subclassing, nicht der Klassenname.

Funktioniert Error.isError() in Safari?

Safari 18.4 und höher unterstützen Error.isError() für reguläre Error-Objekte, allerdings ist die Unterstützung nur teilweise gegeben. Safari gibt derzeit für DOMException-Instanzen false zurück, während die Spezifikation und andere Engines true liefern. Wegen dieser Lücke klassifiziert MDN die Methode nicht als Baseline, und web.dev weist darauf hin, dass sie noch nicht einheitlich verfügbar ist. Behandeln Sie den DOMException-Fall defensiv, wenn Ihr Code Safari als Zielplattform hat.

Ist Error.isError() schneller als instanceof Error?

Beide sind praktisch Prüfungen mit konstanter Laufzeit, Performance ist also nicht der Grund für einen Wechsel. instanceof läuft die Prototypenkette ab, während Error.isError() ein einzelnes internes Kennzeichen liest, doch der praktische Unterschied ist verschwindend gering. Der eigentliche Vorteil ist Korrektheit: Error.isError() liefert die richtige Antwort für Cross-Realm-Fehler und prototypengefälschte Nachahmungen – Fälle, in denen instanceof stillschweigend versagt. Wählen Sie es für Zuverlässigkeit an den Grenzen von Ausführungskontexten, nicht für Geschwindigkeit.

Open-source session replay

Complete picture for complete understanding

Capture every clue your frontend is leaving so you can instantly get to the root cause of any issue with OpenReplay — the open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data.

Star on GitHub12k

We use cookies to improve your experience. By using our site, you accept cookies.