JS: Error Object
2015-08-13 todo, work in progress .
JavaScript error object, is typically use with the “throw” statement. [see Throw Try Catch Finally]
Error.prototype
Error()
Error(message) → message is a optional message for information purposes.
new Error(…) → same as Error(…).
Properties
message → value is from the argument when Error(...) is called. If none given, it's supplied by browser.
name → a name for the error.
EvalErrorRangeErrorReferenceErrorSyntaxErrorTypeErrorURIError
JavaScript Error Object Tutorial (AI generated)
The Error object in JavaScript is the foundation for error handling. It represents runtime errors or exceptions that occur during program execution. Understanding it is essential for robust, debuggable code.
1. What is the Error Object?
When something goes wrong, JavaScript creates an Error instance (or a subclass). You can throw and catch these objects.
try { throw new Error("Something went wrong!"); } catch (err) { console.log(err); // Error object }
2. Creating an Error
// Basic constructor const err = new Error("This is a custom error message"); // With cause (modern browsers/Node.js) const err2 = new Error("Failed to fetch", { cause: originalError });
3. Core Properties
Every Error instance has these key properties:
| Property | Description | Example |
|---|---|---|
message |
The error description | "File not found" |
name |
Type of error (default: "Error") |
"TypeError" |
stack |
Call stack trace (non-standard but widely supported) | Multi-line string with file/line |
cause |
Underlying error (ES2022+) | Another Error object |
const err = new Error("Cannot read property 'x' of undefined"); console.log(err.name); // "Error" console.log(err.message); // "Cannot read property 'x' of undefined" console.log(err.stack); // Full stack trace
Note: stack is not part of the ECMAScript standard but is implemented in all major engines (V8, SpiderMonkey, JavaScriptCore).
4. Built-in Error Subclasses
JavaScript provides several specialized error types:
TypeError– Wrong type or operation (e.g., calling non-function)ReferenceError– Undeclared variableSyntaxError– Invalid JavaScript syntax (cannot be caught with try/catch in same scope)RangeError– Number out of range (e.g.,Array(10**10))URIError– Malformed URIEvalError– Deprecated (rarely used)AggregateError– Multiple errors (used withPromise.any())InternalError/SystemError(Node.js specific)
try { null.toString(); // TypeError } catch (e) { console.log(e.name); // "TypeError" }
5. Throwing Errors
You can throw any value, but you should always throw an Error instance for proper stack traces.
function divide(a, b) { if (b === 0) { throw new Error("Division by zero"); // Or more specific: // throw new RangeError("Division by zero"); } return a / b; }
Best practice: Throw Error (or subclasses) instead of strings/numbers.
6. Catching and Handling Errors
try { riskyOperation(); } catch (error) { if (error instanceof TypeError) { console.error("Type error occurred:", error.message); } else if (error instanceof ReferenceError) { console.error("Reference error:", error.message); } else { console.error("Unknown error:", error); } // Log stack in development if (process?.env?.NODE_ENV === "development") { console.error(error.stack); } } finally { // Always runs (cleanup) console.log("Cleanup done"); }
Modern pattern – Using cause and structured errors:
try { await fetchData(); } catch (error) { throw new Error("Failed to load user data", { cause: error }); }
7. Custom Error Classes (Recommended)
Since ES6, create your own error types with proper inheritance:
class ValidationError extends Error { constructor(message, field) { super(message); this.name = "ValidationError"; this.field = field; } } class DatabaseError extends Error { constructor(message, originalError) { super(message, { cause: originalError }); this.name = "DatabaseError"; } } // Usage function validateUser(user) { if (!user.email) { throw new ValidationError("Email is required", "email"); } }
Check error type:
try { validateUser({}); } catch (err) { if (err instanceof ValidationError) { console.log(`Validation failed on ${err.field}`); } }
8. Global Error Handling
Browser:
window.addEventListener("error", (event) => { console.log("Uncaught error:", event.error); }); window.addEventListener("unhandledrejection", (event) => { console.log("Unhandled promise rejection:", event.reason); });
Node.js:
process.on("uncaughtException", (err) => { console.error("Uncaught exception:", err); process.exit(1); }); process.on("unhandledRejection", (reason) => { console.error("Unhandled rejection:", reason); });
9. Common Patterns and Best Practices
-
Never swallow errors silently – Always log or rethrow.
-
Use specific error types when possible.
-
Add context to messages.
-
Async error handling:
async function fetchData() { try { const res = await fetch("/api/data"); if (!res.ok) throw new Error(`HTTP ${res.status}`); return await res.json(); } catch (err) { console.error("Fetch failed:", err); throw err; // rethrow or wrap } } -
Error boundaries in React (component level).
-
Avoid
eval()and dangerous constructs that produce hard-to-catchSyntaxError.
10. Debugging Tips
- Use
console.error(err)orerr.stackin development. - Modern dev tools show pretty stack traces with source maps.
- Libraries like
zod,io-ts, orajvthrow structured validation errors.
Quick Reference Cheat Sheet
// Create new Error(message, { cause }); // Throw throw new TypeError("..."); // Check if (error instanceof Error) { ... } // Custom class MyError extends Error { constructor(msg) { super(msg); this.name = "MyError"; } }
The Error object is simple yet powerful. Mastering it turns "random crashes" into predictable, debuggable failures.
Further Reading:
- MDN: Error
- ECMAScript spec for error handling.
Practice by building a small utility that wraps all your async functions with consistent error logging! Let me know if you want a deeper dive into any section (e.g., error handling in async/await, libraries like neverthrow, or Node.js specifics).