ReviseAlgo Logo

Exception Handling

try-catch Block

Master try-catch syntax structures, catch block inheritance ordering rules, and clean exception re-throwing.

Interview: Frequently tested: catch block ordering compiler rules, unreachable catch block errors, and exception re-throwing with cause.

Last Updated: June 13, 2026 10 min read

The try-catch block is the primary construct used to intercept and handle exceptions. Java enforces strict compiler rules regarding the order in which multiple catch blocks must be declared based on type hierarchies.

Sequential Checking

Catch blocks are evaluated sequentially from top to bottom. The first catch block matching the exception type executes.

Inheritance Order

Subclass exceptions must appear above superclass exceptions. Reversing this order generates a compile-time error.

Chaining & Re-throw

Exceptions can be caught, logged, and re-thrown. Always attach the original exception as the cause to preserve history.

Catch Block Inheritance Ordering Rules

When handling multiple exception types, order is critical. Because a parent exception catch block (e.g. catch (Exception e)) can catch any of its subclass instances, the compiler enforces subclass-first ordering:

  • Specific First: Always catch subclasses (e.g. FileNotFoundException) before parent classes (e.g. IOException).
  • Compiler Check: If you place catch (IOException e) above catch (FileNotFoundException e), the compiler fails with an error: "exception FileNotFoundException has already been caught".

Re-throwing and Exception Chaining

Sometimes a catch block should perform local operations (like rolling back a transaction) but still propagate the error. You can re-throw the exception directly, or wrap it in a high-level exception:

catch (SQLException e) {
    rollbackTransaction();
    throw new DatabaseAccessException("Transaction failed", e); // Exception Chaining
}

Passing the original exception e to the constructor preserves the full stack trace, ensuring the root cause is not lost.

Common Pitfalls

  • Swallowing Exceptions: Catching an exception with an empty body (e.g., catch (Exception e) {}). This hides failures, making bugs nearly impossible to diagnose.
  • Incorrect Ordering: Swapping catch block order and failing to compile due to unreachable exception blocks.

Best Practices

  • Always Log or Re-throw: Never swallow exceptions. At minimum, log the exception (e.g. logger.error("Error occurred", e);).
  • Expose Domain Exceptions: Wrap low-level technical exceptions in meaningful domain-specific exceptions before throwing them across boundaries.

Interview-Relevant Information

Q1: Why does the compiler fail if we catch Exception before IOException?
Answer: Because catch blocks are evaluated in order. Since Exception is the superclass of IOException, the first block would catch all IOExceptions, making the second block unreachable. The compiler explicitly forbids unreachable catch blocks.

Q2: What is exception chaining?
Answer: Exception chaining is the practice of wrapping a low-level exception inside a newly thrown high-level exception. This is done by passing the original exception (cause) to the constructor of the new exception, preserving the root cause stack trace.

Quick Checklist

Can you explain catch block ordering rules, write an exception chaining block, and explain why swallowing exceptions is dangerous? If yes, you understand try-catch blocks.

Use Cases

Intercepting database access errors and rolling back local transactions.

Wrapping lower-level library exceptions inside custom business errors.

Common Mistakes

Placing parent exceptions above specific subclass exceptions, causing compilation failures.

Swallowing exceptions by leaving the catch block body empty, masking critical failures.