What it does: Prevents your script from crashing when errors happen - lets you handle them gracefully instead of the dreaded “script dies.”
How try…catch Actually Works:
Basic Structure:
try {
// Code that might break
let result = riskyOperation();
console.log("Success!");
} catch (err) {
// Handle the error
console.log("Something went wrong:", err.message);
}
// Script continues running hereThe Error Object Properties:
What You Get in catch:
try {
nonExistentFunction();
} catch (err) {
console.log(err.name); // "ReferenceError"
console.log(err.message); // "nonExistentFunction is not defined"
console.log(err.stack); // Full call stack trace
console.log(err); // "ReferenceError: nonExistentFunction is not defined"
}Creating Your Own Errors (throw):
Custom Error Creation:
let json = '{"age": 30}'; // Missing name property
try {
let user = JSON.parse(json); // Valid JSON, but incomplete data
if (!user.name) {
throw new Error("Incomplete data: no name"); // Custom error!
}
console.log("Hello", user.name);
} catch (err) {
console.log("Error:", err.message); // "Error: Incomplete data: no name"
}Different Error Types:
javascript
throw new Error("General error");
throw new SyntaxError("Custom syntax error");
throw new ReferenceError("Custom reference error");
throw new TypeError("Custom type error");
// Can even throw primitives (but don't!)
throw "Just a string";
throw 404;
throw true;Rethrowing Pattern:
Only Handle Errors You Know:
javascript
try {
let user = JSON.parse(jsonData);
if (!user.name) {
throw new SyntaxError("Incomplete data: no name");
}
unknownVariable; // Programming mistake!
} catch (err) {
if (err instanceof SyntaxError) {
console.log("Data error:", err.message); // Handle data errors
} else {
throw err; // Rethrow programming errors - don't hide bugs!
}
}try…catch…finally:
finally ALWAYS Runs:
javascript
let start = Date.now();
try {
// Some operation that might fail
riskyOperation();
return "success"; // Even with return, finally runs!
} catch (err) {
return "error"; // Even with return, finally runs!
} finally {
let duration = Date.now() - start;
console.log(`Operation took ${duration}ms`); // ALWAYS executes
}try…finally (without catch):
Cleanup Without Error Handling:
function doSomething() {
startExpensiveResource();
try {
// Do work that might fail
complexOperation();
} finally {
cleanupExpensiveResource(); // Always cleanup, even if error occurs
}
// If error occurred, it bubbles up after cleanup
}Global Error Handling:
Catch All Uncaught Errors:
window.onerror = function(message, url, line, col, error) {
console.log(`Global error: ${message} at ${url}:${line}:${col}`);
// Send to error logging service
return true; // Prevents default browser error handling
};
// Modern way (better):
window.addEventListener('error', function(event) {
console.log('Global error:', event.error);
});Interview Gotchas:
// Gotcha 1: Syntax errors can't be caught
try {
if (true { // Missing )
} catch (err) {
console.log("Won't work"); // Script won't even parse
}
// Gotcha 2: Async errors escape
try {
setTimeout(() => { throw new Error("Async error"); }, 100);
} catch (err) {
console.log("Won't catch async errors");
}
// Gotcha 3: finally runs even with return
function test() {
try {
return 1;
} finally {
console.log("This runs first!"); // Runs before return
}
}
// Gotcha 4: Variable scope
try {
let x = 1;
} catch (err) {
let y = 2;
} finally {
let z = 3;
}
// x, y, z are not accessible here!
// Gotcha 5: Rethrowing preserves original stack
try {
throw new Error("Original");
} catch (err) {
throw err; // Preserves original stack trace
// vs
throw new Error(err.message); // Creates new stack trace
}Never Get Tricked - Follow These Rules:
- Syntax errors kill before try…catch - code must be valid JavaScript
- Async needs its own try…catch - setTimeout, promises escape outer try…catch
- finally ALWAYS runs - even with return statements
- Rethrow unknown errors - don’t hide programming bugs
- Use specific error types - SyntaxError, TypeError, etc. for different scenarios
- Global handlers for fallback - catch what you missed
Bottom line: try…catch is for expected failures, finally is for cleanup, throw is for custom errors, and rethrowing prevents hiding bugs.
