Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt

Use this file to discover all available pages before exploring further.

The try...catch...finally statement is a synchronous control flow construct used to handle runtime exceptions. It evaluates a block of code, intercepts any exceptions thrown during that evaluation, and guarantees the execution of a final block of code regardless of whether an exception occurred.
try {
  // Statements to be evaluated
} catch (exception) {
  // Statements to execute if an exception is thrown in the try block
} finally {
  // Statements to execute unconditionally after try/catch evaluation
}

Structural Requirements

A try block must be followed by at least one catch block, one finally block, or both. A standalone try block results in a SyntaxError. Variables declared with let or const inside any of these blocks are block-scoped and cannot be accessed outside of their respective blocks.

The try Block

The try block contains the code to be executed. If the JavaScript engine encounters a runtime error, or if a throw statement is explicitly invoked within this block, the execution of the try block immediately halts. Control flow is then transferred to the catch block (if present) or the finally block.

The catch Block

The catch block executes only if an exception is thrown within the try block.
  • Exception Binding: By default, the catch clause defines an identifier (e.g., exception) that receives the thrown value or Error object. This identifier is scoped strictly to the catch block.
  • Optional Catch Binding: As of ES2019, if the exception object is not required for error handling, the binding and its parentheses can be omitted entirely.
// Standard catch binding
try {
  throw new Error("Failure");
} catch (err) {
  console.error(err.message);
}

// Optional catch binding (ES2019+)
try {
  throw new Error("Failure");
} catch {
  console.error("An error occurred, but the exception object is ignored.");
}

The finally Block

The finally block executes after the try block and catch block(s) have finished executing, but before the statements following the entire try...catch...finally construct. The finally block executes unconditionally. It will run even if:
  1. No exception is thrown.
  2. An exception is thrown but not caught (e.g., a try...finally construct without a catch).
  3. An exception is thrown within the catch block itself.

Control Flow Overrides in finally

The finally block intercepts and overrides control flow statements (return, throw, break, continue) initiated in the try or catch blocks. If a try or catch block contains a return statement, the finally block will still execute before the function actually returns. Furthermore, if the finally block also contains a return statement, the value returned by the finally block supersedes the value returned by the try or catch block.
function evaluateFlow() {
  try {
    return 1;
  } catch {
    return 2;
  } finally {
    return 3; 
  }
}

console.log(evaluateFlow()); // Outputs: 3

Synchronous Execution Limitation

The try...catch mechanism operates synchronously on the call stack. It cannot intercept exceptions thrown inside asynchronous callbacks (such as setTimeout or event listeners) because the try...catch block will have already finished executing by the time the callback is pushed to the call stack. To handle asynchronous errors, the try...catch construct must either be placed inside the callback itself, or used in conjunction with await inside an async function.
Master JavaScript with Deep Grasping Methodology!Learn More