Skip to main content
The try-catch construct in Dart is a structured exception handling mechanism used to intercept and manage runtime errors. It prevents unhandled exceptions from terminating the current isolate by transferring control flow to designated error-handling blocks.

Syntax Overview

Dart provides a flexible syntax allowing type-specific interception, generic interception, and unconditional execution blocks.
try {
  // Code subject to exception monitoring
} on SpecificExceptionType catch (e, s) {
  // Type-bound interception
} catch (e, s) {
  // Generic interception
} finally {
  // Unconditional execution
}

Component Mechanics

  • try: Defines the lexical scope for exception monitoring. If an exception is thrown within this block, normal execution halts, and the runtime searches down the chain of handlers.
  • on: A type-matching clause. It evaluates the runtime type of the thrown object. Dart allows throwing any non-null Object, so the on clause is critical for routing specific types (e.g., FormatException, TypeError) to their respective handlers.
  • catch: Binds the intercepted exception to local variables. It accepts one or two parameters:
    • First parameter (e): The thrown object itself.
    • Second parameter (s): An optional StackTrace object representing the execution call stack at the exact point the exception was thrown.
  • finally: A block guaranteed to execute regardless of whether an exception was thrown, caught, or remained unhandled within the try block. If an unhandled exception exists, it is propagated up the call stack only after the finally block completes.

Handler Resolution Order

The runtime evaluates on and catch clauses sequentially from top to bottom. The first clause that matches the thrown object’s type is executed. Subsequent clauses are ignored. A standalone catch block acts as a catch-all (equivalent to on Object catch) and must be placed at the bottom of the handler chain.

The rethrow Keyword

Dart provides the rethrow keyword specifically for use within catch blocks. It propagates the caught exception to the next enclosing try-catch block or up the call stack.
try {
  // ...
} catch (e, s) {
  rethrow; 
}
Unlike manually throwing the caught exception (throw e;), rethrow preserves the original StackTrace. Manually throwing resets the stack trace to the location of the throw statement, destroying the context of the original error.
Tired of Poor Dart Skills? Fix That With Deep Grasping!Learn More