Exception Handling

Errors are an inevitable part of software development. In JavaScript, we manage errors through Exceptions. An uncaught exception will "Bubble Up" the call stack and eventually terminate the script if it reaches the global scope without being handled.


1. The try...catch...finally Block

The primary syntax for handling errors is the try-catch block.

try {
    const data = JSON.parse(untrustedJson);
} catch (error) {
    console.error("Malformed JSON:", error.message);
} finally {
    console.log("Cleanup: closing database connection.");
}

2. The Error Object

When an error occurs, JavaScript creates a specialized Error Object.


3. Propagation: Error Bubbling

If an error is thrown inside a function and is NOT caught, the engine stops the function, moves up to the Caller function, and looks for a catch there. This continues until:

  1. It is caught by a try...catch.
  2. It reaches the Global Execution Context, triggering a browser console error or a Node.js crash.

4. Custom Error Classes

For production applications, you should extend the built-in Error class to create domain-specific error types.

class ValidationError extends Error {
    constructor(message) {
        super(message);
        this.name = "ValidationError";
    }
}

throw new ValidationError("Username too short");

Interview Pro-Tips: Async Error Handling

Remember that try...catch does NOT work for asynchronous callbacks or standard Promises unless you use await.


Technical Summary

  1. Throwing: Use the throw keyword to manually trigger an error.
  2. Immutability: Error objects once thrown should be treated as diagnostic data.
  3. Best Practice: Always catch specific errors if possible, and avoid empty catch blocks which "Swallow" bugs.