How to Check if a Value of Type "Error" in JavaScript
In JavaScript, especially when handling exceptions with try...catch blocks, it's a good practice to check if the "thing" you've caught is actually an instance of the Error class. This allows you to safely access properties like .message and .stack and to distinguish between intentional errors and other values that might have been thrown.
This guide will teach you the standard, built-in method for this task using the instanceof operator. You will also learn about the "duck typing" approach and the specific edge cases (like iframes) where it might be necessary.
The Core Method (Recommended): The instanceof Operator
The instanceof operator is the simplest, most direct, and most readable way to check if an object is an instance of a specific class. It checks the object's prototype chain to see if it was created from the given constructor.
The syntax:
myVariable instanceof Error
where:
- This expression will return
trueifmyVariableis an instance ofError(or a class that extendsError). - It will return
falsefor all other values (plain objects, strings, numbers, etc.).
Basic Example: A Simple Error Check
This script shows how to use instanceof inside a catch block to safely handle a thrown error.
function performTask() {
// Simulate a failure by throwing a real Error object
throw new Error('Something went wrong!');
}
try {
performTask();
} catch (error) {
console.log('An exception was caught.');
// ✅ Use instanceof to check the type
if (error instanceof Error) {
console.log('The caught value is a real Error object.');
console.log('Error Message:', error.message);
} else {
console.log('The caught value is NOT an Error object.');
console.log('Value:', error);
}
}
Output:
An exception was caught.
The caught value is a real Error object.
Error Message: Something went wrong!
Handling Custom Errors
A major advantage of instanceof is that it correctly identifies instances of custom error classes that extend the base Error class.
// A custom error class
class NetworkError extends Error {
constructor(message) {
super(message);
this.name = 'NetworkError';
}
}
const myError = new NetworkError('Failed to connect.');
// It is an instance of its own class
console.log(myError instanceof NetworkError); // Output: true
// It is also an instance of the base Error class
console.log(myError instanceof Error); // Output: true
This makes instanceof a very powerful and reliable tool for error handling hierarchies.
An Edge Case: The "Duck Typing" Method
There is one specific, uncommon scenario where instanceof can fail: when checking an error that originated from a different JavaScript "realm," such as another <iframe> or a web worker. In these cases, the error object from the iframe will have a different Error constructor than the one in your main window, so instanceof will return false.
For this edge case, you can use "duck typing": "If it walks like a duck and quacks like a duck, it's a duck." We check if the object has the properties we expect an error to have, like .message and .stack.
function isErrorLike(value) {
return value !== null &&
typeof value === 'object' &&
typeof value.message === 'string' &&
typeof value.stack === 'string';
}
const myError = new Error('Something went wrong.');
console.log(isErrorLike(myError)); // Output: true
const notAnError = { message: 'Hello', stack: 'Some stack' };
// ⛔️ This is a false positive
console.log(isErrorLike(notAnError)); // Output: true
Warning: As shown, this method is not foolproof and can be tricked by a plain object that happens to have the same property names. For this reason, it should only be used when you know you need to handle cross-realm errors. For all other cases, instanceof is superior.
Conclusion
Checking if a value is an Error is a crucial part of robust error handling.
The key takeaways are:
- The
instanceof Erroroperator is the standard, recommended, and most reliable method for this task. It is clear, direct, and correctly handles custom error subclasses. - Use
instanceofinside atry...catchblock to ensure you are working with a realErrorobject before you try to access its.messageor.stackproperties. - The "duck typing" method (checking for
.messageand.stackproperties) should only be used for the specific edge case of handling errors that come from a different JavaScript realm, like an<iframe>.