Your language · Java
Exceptions
Raising, catching and cleaning up after errors, and custom exceptions.
Learn: Exceptions in Java9 minute read
An exception is an object that Java throws when something goes wrong, such as a missing file, a bad number or an element that never appears. Test code meets exceptions all the time, so interviewers ask about the class hierarchy, the rules of try, catch and finally, and how you write your own exceptions so that failures are easy to read.
Step 1: the hierarchy, checked and unchecked
Everything that can be thrown extends Throwable. Below it, Error covers serious JVM problems (the JVM is the program that runs Java code) that code normally does not catch, such as running out of memory, and Exception covers problems a program can handle. To catch an exception means to handle it in a catch block; a caller is the code that calls a method.
A checked exception is any Exception subclass outside RuntimeException, such as IOException or InterruptedException. The compiler forces every caller to catch it or declare it with throws. An unchecked exception is a RuntimeException or an Error, such as NullPointerException or NumberFormatException; the compiler does not force handling. Selenium's (a tool that controls a browser from code) NoSuchElementException and TimeoutException extend WebDriverException, a RuntimeException, so they are unchecked.
Step 2: try, catch and finally
- Catch blocks are tried top to bottom, and only the first match runs. A parent type before its subclass (a class that extends it) is a compile error, so go from specific to general.
- One block can catch unrelated types:
catch (IOException | SQLException e). finallyruns whether or not something was thrown, even afterreturn. It does not run if the JVM stops first, as withSystem.exit.- A
tryneeds a catch, a finally or resources; a bare try does not compile.
public class Main {
static String parse(String text) {
try {
System.out.print("try ");
int n = Integer.parseInt(text);
return "number " + n;
} catch (NumberFormatException e) {
System.out.print("catch ");
return "not a number";
} finally {
System.out.print("finally ");
}
}
static int risky() {
try { return 1; } finally { return 2; } // finally wins: avoid this
}
public static void main(String[] args) {
System.out.println(parse("42"));
System.out.println(parse("abc"));
System.out.println(risky());
try {
Object o = "text";
Integer i = (Integer) o;
} catch (ClassCastException | IllegalStateException e) {
System.out.println("caught " + e.getClass().getSimpleName());
}
}
}
try finally number 42 try catch finally not a number 2 caught ClassCastException
risky() returns 2: a return in finally replaces the real result and can swallow an exception, so never return from finally.
Step 3: try-with-resources, throw and throws
Anything that implements AutoCloseable (an interface with a close() method), such as a file reader or a database connection, can be opened in the try header. Java closes it at the end of the block, in reverse order of opening, even when an exception is thrown. If closing also fails, that second exception is attached to the first as a "suppressed" exception instead of hiding it.
throw raises one exception object now: throw new IllegalArgumentException("timeout must be positive");. throws in a method header lists the checked exceptions the method may pass to its caller. An overriding method may declare fewer or narrower checked exceptions, never broader ones.
Step 4: custom exceptions
Write your own exception when a framework error deserves a clear name and message. Extend RuntimeException for most framework errors, or Exception when callers must handle it. Always offer a constructor that keeps the cause (the original exception), so the original stack trace (the list of method calls that led to the error) is not lost.
import java.io.*;
import java.nio.file.*;
class TestDataException extends RuntimeException {
TestDataException(String message, Throwable cause) { super(message, cause); }
}
class Resource implements AutoCloseable {
private final String name;
Resource(String name) { this.name = name; System.out.println("open " + name); }
@Override public void close() { System.out.println("close " + name); }
}
public class Main {
static String readUsers(String file) {
try {
return Files.readString(Path.of(file));
} catch (IOException e) {
throw new TestDataException("Cannot read test data: " + file, e);
}
}
public static void main(String[] args) {
try (Resource a = new Resource("report"); Resource b = new Resource("log")) {
System.out.println("writing");
}
try {
readUsers("missing-users.csv");
} catch (TestDataException e) {
System.out.println(e.getMessage());
System.out.println("cause: " + e.getCause().getClass().getSimpleName());
}
}
}
open report open log writing close log close report Cannot read test data: missing-users.csv cause: NoSuchFileException
How to answer in an interview
For "checked or unchecked?", give the rule and an example of each: "Checked exceptions extend Exception but not RuntimeException, like IOException; the compiler makes me catch or declare them. Unchecked ones, like NullPointerException or Selenium's NoSuchElementException, are not enforced." For a custom exception, show the two-line class with a cause constructor and say where you throw it.
Common mistakes
- Catching
Exceptionjust to print it and carry on (called swallowing the exception), so a broken test passes. - Wrapping an exception without passing the cause.
- Putting
catch (Exception e)before a more specific catch. - Returning from
finally. - Using exceptions for normal flow. To check that an element is absent, use
findElements(...).isEmpty()instead of catchingNoSuchElementException.
Recap
Throwable splits into Error and Exception. Checked exceptions must be caught or declared; RuntimeException and Error are unchecked. Catch from specific to general, keep finally for clean-up, and prefer try-with-resources. Custom exceptions should carry a clear message and the original cause.
10 questions0/10 solved
| Status | Question | Difficulty | Asked in |
|---|---|---|---|
| Not started | Checked or unchecked? | Easy | Asked in: Accenture, Infosys, TCS +1 |
| Not started | Checked vs unchecked exceptions and the hierarchy | Easy-Medium | Asked in: Accenture, Infosys, TCS +1 |
| Pro+ | throw versus throws | Easy | Asked in: Capgemini, Infosys, TCS +1 |
| Pro+ | try, catch and finally: the rules | Medium | Asked in: Accenture, Capgemini, Cognizant +2 |
| Pro+ | Catch blocks in the wrong order | Medium | Asked in: Accenture, Capgemini, Cognizant +2 |
| Pro+ | return in try and finally | Medium | Asked in: Accenture, Capgemini, Cognizant +2 |
| Pro+ | Write and use a custom exception | Medium | Asked in: Wipro |
| Pro+ | try-with-resources | Medium | Asked in: ISS STOXX |
| Pro+ | Does finally always run? | Easy-Medium | Asked in: Accenture, Capgemini, Cognizant +2 |
| Pro+ | Overriding a method that throws a checked exception | Medium-Hard | Asked in: Accenture, Capgemini, Infosys +2 |
The first 2 questions of each topic are free. Pro+ opens every question.