In software engineering, runtime errors are inevitable—whether from invalid user input, network outages, or corrupted data payloads. Without robust exception handling, unhandled errors crash the JavaScript execution thread. The try..catch..finally statement constructs a resilient boundary that intercepts errors gracefully.
try {
// 1. Code that might throw a runtime exception
console.log("Attempting database parse operation...");
let result = JSON.parse("corrupted-raw-data-string");
console.log("This line will never be reached!");
} catch (error) {
// 2. Intercept and handle the error gracefully
console.error("Error Caught:", error.name, "-", error.message);
} finally {
// 3. ALWAYS executes unconditionally (Cleanup operations)
console.log("Cleanup: Closing connection pool.");
}
You can throw native errors or create enterprise domain-specific error classes by extending the built-in Error class:
class ValidationError extends Error {
constructor(message, field) {
super(message);
this.name = "ValidationError";
this.field = field;
}
}
function processPayment(amount) {
if (typeof amount !== "number" || isNaN(amount)) {
throw new TypeError("Payment amount must be a valid number.");
}
if (amount <= 0) {
throw new ValidationError("Payment amount must be greater than zero.", "amount");
}
return `Processed payment of ₹${amount}`;
}
try {
processPayment(-50);
} catch (err) {
if (err instanceof ValidationError) {
console.warn(`Validation failed on field [${err.field}]: ${err.message}`);
} else {
console.error("System Error:", err.message);
}
}
Exam Question: "What properties are provided on a standard JavaScript Error instance?"
error.name: The error type string (e.g., "TypeError", "ReferenceError").error.message: A human-readable textual description of what went wrong.error.stack: The full V8 stack trace showing exact filenames, functions, and line numbers where the exception originated.How do professional developers inspect and step through running code? Proceed to: JavaScript Debugging & DevTools Mastery →