Next-Gen App & Browser Testing Cloud
Trusted by 2 Mn+ QAs & Devs to accelerate their release cycles

In Java, an Error is a serious, usually unrecoverable problem that the application should not try to handle — such as OutOfMemoryError or StackOverflowError — while an Exception is a condition the application can catch and recover from, such as IOException or NullPointerException. Both Error and Exception extend the common superclass Throwable, but only Exceptions are meant to be caught and handled in normal program flow.
Below, we break down the Throwable hierarchy, compare Errors and Exceptions side by side, explain checked versus unchecked exceptions, show how to handle exceptions with try/catch/finally, and clear up the related testing terms — error, defect, bug, and failure.
An Error represents a serious problem that a reasonable application should not try to catch. In Java these are subclasses of java.lang.Error, and they almost always originate from the environment the program runs in — the JVM, the operating system, or the hardware — rather than from a logical mistake in a single line of business code. Errors typically surface at runtime, indicate the system is in an abnormal state, and are generally unrecoverable.
Classic examples include:
Because these conditions reflect the health of the runtime, catching them rarely helps. The correct response is usually to let the application terminate, then fix the root cause — increase the heap size, remove the runaway recursion, or correct the deployment so the missing class is on the classpath.
An Exception is an event that disrupts the normal flow of a program but which the application can anticipate, catch, and recover from. Exceptions are subclasses of java.lang.Exception and usually originate in the application code or the data it processes — a missing file, a bad network response, a null reference, or an invalid array index. Unlike Errors, exceptions are a normal, expected part of robust programming, and handling them gracefully is what keeps an application running instead of crashing.
Common examples include:
The key distinction is intent: exceptions are designed to be caught. When an exception occurs, your code can log it, retry the operation, fall back to a default, or surface a friendly message to the user, and then continue running. If you are new to the concept, our primer on what exceptions mean covers the fundamentals in more detail.
Everything that can be thrown or caught in Java descends from a single root class, java.lang.Throwable. Directly beneath it sit two branches — Error and Exception — which makes them siblings, not parent and child. Under Exception, the RuntimeException branch holds the unchecked exceptions, while every other Exception subclass is checked.
java.lang.Throwable
├── java.lang.Error // serious, do NOT catch
│ ├── OutOfMemoryError
│ ├── StackOverflowError
│ └── NoClassDefFoundError
└── java.lang.Exception // catch and recover
├── IOException // checked
├── SQLException // checked
└── java.lang.RuntimeException // unchecked
├── NullPointerException
├── ArrayIndexOutOfBoundsException
└── NumberFormatExceptionBecause both branches extend Throwable, you could write catch (Throwable t) to trap an Error, but that is almost always the wrong choice — it hides serious JVM failures behind ordinary error handling. The hierarchy exists precisely so you can catch Exception (and its subclasses) without accidentally swallowing an Error.
The following summarizes the practical differences testers and developers care about most:
Within the Exception branch, Java draws a second important line. A checked exception is verified by the compiler: if a method can throw one, you must either catch it or declare it with throws, or the code will not compile. IOException, SQLException, and ClassNotFoundException are checked. They model recoverable conditions outside your control, like a file that may not exist.
An unchecked exception extends RuntimeException and is not enforced by the compiler. NullPointerException, ArrayIndexOutOfBoundsException, and NumberFormatException are unchecked. They usually signal a programming bug that you should fix rather than catch. The contrast is shown below:
// CHECKED — compiler forces you to handle or declare it
public void readFile(String path) throws IOException {
FileReader reader = new FileReader(path); // may throw IOException
reader.read();
reader.close();
}
// UNCHECKED — compiles fine, fails only at runtime
public int parse(String value) {
return Integer.parseInt(value); // throws NumberFormatException if not a number
}A useful mnemonic: checked = "expected, handle it" and unchecked = "your bug, fix it." Errors, for completeness, are also unchecked — the compiler never forces you to handle them.
Java handles exceptions with the try, catch, and finally blocks. Code that might throw goes in try; each catch handles a specific exception type (most specific first); and finally always runs, whether or not an exception occurred, making it ideal for releasing resources. For a deeper treatment of the mechanisms, types, and patterns involved, see our full guide to exception handling.
public class FileProcessor {
public static void main(String[] args) {
try {
int[] data = readNumbers("data.txt");
System.out.println("First value: " + data[0]);
} catch (IOException e) {
// recover from a file/network problem
System.err.println("Could not read file: " + e.getMessage());
} catch (ArrayIndexOutOfBoundsException e) {
// recover from a logic problem with the data
System.err.println("File was empty: " + e.getMessage());
} finally {
// always runs — clean up resources here
System.out.println("Processing finished.");
}
}
}Best practices to keep handling robust:
Outside of Java, the word "error" also has a specific meaning in software testing terminology, and it is easy to confuse it with a programming Error. In testing, these four terms describe distinct stages of how a problem appears:
So a tester might say: a developer's error created a defect (bug) in the code, which caused a failure in production. To dive deeper into classification, see our guide on the different types of bugs in software testing.
So, what is the difference between an Error and an Exception? An Error is a serious, usually unrecoverable problem from the runtime environment that you should not catch, while an Exception is a recoverable condition in your code or data that you can and should handle with try/catch/finally. Both extend Throwable as siblings, exceptions split into checked and unchecked, and only exceptions belong in your normal error-handling flow. Identify which one you are facing, handle exceptions deliberately, let errors fail fast, and validate that behavior across real environments to ship reliable software.
No. Error and Exception are sibling classes. Both extend the Throwable superclass, but neither extends the other. Error represents serious JVM-level problems, while Exception represents conditions an application can reasonably anticipate and handle.
Technically yes, because Error extends Throwable, so catch (Throwable t) or catch (Error e) will compile. In practice you should not, because Errors like OutOfMemoryError signal the JVM is in an unrecoverable state and continuing usually causes more damage.
A checked exception (such as IOException) is verified at compile time and must be caught or declared with throws. An unchecked exception extends RuntimeException, is not enforced by the compiler, and usually signals a programming bug like NullPointerException.
In testing terminology, a bug or defect is a flaw a developer introduces in the code, an error is the human mistake that produces that defect, and a failure is the visible incorrect behavior an end user sees when the defective code runs.
No. NullPointerException is an unchecked Exception caused by accessing a null reference in your code, and you can recover from it. OutOfMemoryError is an Error raised by the JVM when heap memory is exhausted, and it is generally not recoverable.
Errors occur only at runtime and cannot be recovered from. Exceptions can surface at either stage: checked exceptions are detected by the compiler at compile time and must be handled or declared, while unchecked exceptions such as NullPointerException appear at runtime when the offending code executes.
Errors signal that the runtime environment itself is broken, for example the heap is exhausted or the call stack is full. Because the JVM is already in an abnormal state, catching the Error and continuing usually leads to further corruption, so the safe response is to let the application terminate and fix the root cause.
KaneAI - Testing Assistant
World’s first AI-Native E2E testing agent.

TestMu AI forEnterprise
Get access to solutions built on Enterprise
grade security, privacy, & compliance