Error.isError(): Checking for Errors Reliably
In modern JavaScript, verifying whether a value is an Error object can be surprisingly tricky. While developers historically relied on instanceof Error, this approach has major flaws in multi-context web applications (such as those using iframes, Web Workers, or Node.js VM modules).
To solve this, JavaScript introduced Error.isError(), a static method that reliably detects Error objects across different global contexts (realms).
The Legacy Way: instanceof Error
For years, the standard way to check if a thrown value was an error was to use the instanceof operator:
try {
performAction();
} catch (err) {
if (err instanceof Error) {
console.log("It is an error:", err.message);
} else {
console.log("Something else was thrown:", err);
}
}The Problem: Cross-Realm Failures
A "realm" in JavaScript represents a global execution context. Each realm (e.g., an <iframe>, a Web Worker, a popup window, or a Node.js VM context) has its own global scope and its own unique built-in constructor objects—including its own Error constructor.
If an error is thrown inside an <iframe> and passed to the parent window, the parent window's Error constructor will not recognize it:
// Inside parent window
const iframe = document.querySelector('iframe');
const iframeWindow = iframe.contentWindow;
// Create an Error inside the iframe
const iframeError = new iframeWindow.Error("Something went wrong inside the iframe");
console.log(iframeError instanceof Error);
// ❌ Returns: false (because iframeError was created using iframeWindow.Error, not window.Error)Because instanceof checks if the prototype of the constructor (in the current realm) is in the prototype chain of the object, it fails when comparing objects across boundaries.
The Modern Solution: Error.isError()
Error.isError() behaves similarly to the popular Array.isArray() method. It inspects the internal slots of the object rather than its prototype chain, allowing it to identify Error objects regardless of which iframe, worker, or realm they originated from.
const iframe = document.querySelector('iframe');
const iframeWindow = iframe.contentWindow;
const iframeError = new iframeWindow.Error("Iframe error");
// ❌ Legacy check
console.log(iframeError instanceof Error); // false
// âś… Modern check
console.log(Error.isError(iframeError)); // trueSupported Error Types
Error.isError() returns true for the base Error object as well as all built-in subclasses:
EvalErrorRangeErrorReferenceErrorSyntaxErrorTypeErrorURIError- Custom error classes that inherit from
Error
Browser Support & Fallback / Polyfill
Error.isError() is a relatively new feature (supported in Chrome 127+, Firefox 128+, Node.js 22.4.0+). If you need to support older browsers, you should implement a fallback helper.
Here is how you can write a robust, production-safe helper function to check for errors across all environments:
function isError(value) {
// 1. Use the native method if available
if (typeof Error.isError === 'function') {
return Error.isError(value);
}
// 2. Fallback for older browsers (using prototype string check)
return (
value instanceof Error ||
Object.prototype.toString.call(value) === '[object Error]'
);
}
// Usage
try {
// some code
} catch (err) {
if (isError(err)) {
console.error(err.message);
}
}Summary of Differences
| Feature | instanceof Error | Error.isError() |
|---|---|---|
| Verification Logic | Checks prototype chain | Checks internal JS object slots |
| Works with iframes? | ❌ No | ✅ Yes |
| Works with Web Workers? | ❌ No | ✅ Yes |
| Works with custom Errors? | âś… Yes | âś… Yes |
| Older Browser Support | ✅ Yes (Legacy) | ⚠️ Needs polyfill/fallback |