Sitemap

99% of Java Developers Handle Exceptions Wrong — Here’s the Right Way

5 min readJul 8, 2026

--

“Great developers don’t prevent exceptions — they design systems that handle them gracefully.”

Every Java developer has encountered an exception.

Sometimes it’s a simple NullPointerException.
Sometimes it's a SQLException.
And sometimes it's a production issue that wakes you up at 2 AM.

The difference between a junior and senior developer isn’t whether exceptions occur — it’s how they are handled.

In this guide, we’ll go from Core Java Exception Handling all the way to Production-ready Spring Boot Global Exception Handling, including best practices, HTTP status codes, custom exceptions, validation, and interview questions.

Press enter or click to view image in full size
The Complete Exception Handling Cheat Sheet for Java & Spring Boot — From try-catch to Production-Ready REST APIs. Save it for your next interview or project!

What is an Exception?

An Exception is an unexpected event that interrupts the normal execution of a program.

Example:

int a = 10;
int b = 0;
System.out.println(a / b);

Output

java.lang.ArithmeticException: / by zero

The JVM stops the normal execution because the exception wasn’t handled.

Exception Hierarchy

                 Object
|
Throwable
/ \
Error Exception
|
RuntimeException

Understanding this hierarchy is one of the most important Java interview topics.

Error vs Exception

Error

Errors represent serious JVM problems.

Examples

  • OutOfMemoryError
  • StackOverflowError
  • VirtualMachineError

Characteristics

  • Generated by JVM
  • Usually unrecoverable
  • Applications shouldn’t try to handle them

Example

while(true){
new int[1000000];
}

Eventually

OutOfMemoryError

Exception

Exceptions represent problems inside the application.

Examples

  • IOException
  • SQLException
  • FileNotFoundException
  • NullPointerException

Unlike Errors, these can often be recovered from.

Types of Exceptions

Java divides exceptions into two categories.

1. Checked Exception (Compile Time)

Compiler forces you to either

  • Handle it
  • Declare it

Example

FileReader reader = new FileReader("abc.txt");

Compiler error

Unhandled exception type FileNotFoundException

Solution

try{
FileReader reader = new FileReader("abc.txt");
}catch(FileNotFoundException e){
e.printStackTrace();
}

Examples

  • IOException
  • SQLException
  • ClassNotFoundException

2. Unchecked Exception (Runtime)

These occur while the program is running.

Compiler doesn’t force handling.

Examples

  • NullPointerException
  • ArithmeticException
  • ArrayIndexOutOfBoundsException
  • IllegalArgumentException

Example

String str = null;
System.out.println(str.length());

Output

NullPointerException

Try-Catch

The simplest way to handle exceptions.

try{
int result = 10 / 0;
}catch(ArithmeticException ex){
System.out.println(ex.getMessage());
}

Output

/ by zero

Multiple Catch Blocks

Different exceptions require different handling.

try{String s = null;
System.out.println(s.length());
}catch(ArithmeticException ex){
System.out.println("Math Error");
}catch(NullPointerException ex){
System.out.println("String is null");
}

Output

String is null

Multi-Catch (Java 7+)

Instead of writing multiple catch blocks.

try{
}catch(IOException | SQLException ex){
}

Cleaner and easier to maintain.

Finally Block

The finally block executes whether an exception occurs or not.

try{
int x = 10;
}finally{
System.out.println("Cleanup");
}

Output

Cleanup

Typical use cases

  • Closing files
  • Closing database connections
  • Releasing locks
  • Cleaning resources

Try-With-Resources

Before Java 7

FileReader reader = new FileReader("file.txt");
try{
// Read file
}finally{
reader.close();
}

Modern Java

try(FileReader reader = new FileReader("file.txt")){
// Read file
}

No explicit close required.

Resources implementing AutoCloseable are automatically closed.

throw Keyword

Used to manually create an exception.

if(age < 18){
throw new RuntimeException("Not eligible");
}

Use it when business rules fail.

throws Keyword

Used in method signatures.

public void readFile() throws IOException{}

Meaning

“This method may throw an IOException. Whoever calls it must handle it.”

Custom Exceptions

Business applications rarely rely only on Java exceptions.

Get Parmeshwar Pardeshi’s stories in your inbox

Join Medium for free to get updates from this writer.

Instead, create meaningful exceptions.

public class PaymentException extends RuntimeException{
public PaymentException(String message){
super(message);
}
}

Usage

throw new PaymentException("Payment failed");

Benefits

  • Better readability
  • Domain-specific
  • Easier debugging

Exception Propagation

Exceptions travel upward until handled.

Example

method1()
↓
method2()
↓
method3()

If method3() throws an exception

↓

method2() receives it

↓

method1() receives it

↓

Application crashes if nobody handles it.

Java Exception Best Practices

Good

Catch only what you can recover from.

catch(IOException ex){
log.error("Unable to read file", ex);
}

Avoid

catch(Exception ex){
}

Never swallow exceptions.

Avoid Printing Stack Trace

Bad

e.printStackTrace();

Instead

logger.error("Payment failed", e);

Never Use Exceptions for Normal Flow

Bad

try{
list.get(10);
}catch(Exception e){
}

Use proper validation instead.

Spring Boot Exception Handling

Spring Boot provides multiple levels of exception handling.

Controller-Level Handling

Useful when handling exceptions inside one controller.

@ExceptionHandler(PaymentNotFoundException.class)
public ResponseEntity<String> handle(){
return ResponseEntity
.status(HttpStatus.NOT_FOUND)
.body("Payment not found");
}

Suitable for small applications.

Service Layer Exceptions

Business validation belongs in the service layer.

public Payment find(Long id){
return repository.findById(id)
.orElseThrow(() ->
new PaymentNotFoundException(
"Payment not found"
));
}

Global Exception Handling

Recommended for production systems.

@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(PaymentNotFoundException.class)
public ResponseEntity<Object> handle(
PaymentNotFoundException ex){
return ResponseEntity
.status(HttpStatus.NOT_FOUND)
.body(ex.getMessage());
}
}

Benefits

  • Centralized
  • Clean controllers
  • Reusable
  • Consistent responses

Validation Exception Handling

DTO

public class PaymentRequest {
@NotBlank
private String sender;
@NotNull
private BigDecimal amount;
}

Controller

@PostMapping
public void create(
@Valid
@RequestBody PaymentRequest request){
}

If validation fails

Sender must not be blank
Amount must not be null

Global Handler

@ExceptionHandler(
MethodArgumentNotValidException.class
)

Return meaningful validation messages.

Standard Error Response

Instead of

Payment Not Found

Return

{
"timestamp":"2026-07-08T10:20:15",
"status":404,
"error":"Not Found",
"message":"Payment not found",
"path":"/payments/123"
}

Production APIs should always return structured error responses.

Spring Boot Exception Flow

HTTP Request
│
▼
Controller
│
▼
Service
│
▼
Repository
│
Exception Occurs
│
▼
@RestControllerAdvice
│
▼
Error Response
│
▼
HTTP Response

HTTP Status Codes Every Backend Developer Should Know

1xx — Informational

CodeMeaning100Continue101Switching Protocols

2xx — Success

CodeMeaning200OK201Created202Accepted204No Content206Partial Content

3xx — Redirection

CodeMeaning301Moved Permanently302Found304Not Modified307Temporary Redirect308Permanent Redirect

4xx — Client Errors

CodeMeaning400Bad Request401Unauthorized403Forbidden404Not Found405Method Not Allowed409Conflict415Unsupported Media Type422Unprocessable Entity429Too Many Requests

5xx — Server Errors

CodeMeaning500Internal Server Error501Not Implemented502Bad Gateway503Service Unavailable504Gateway Timeout

Why Most Business Exceptions Should Extend RuntimeException

Many experienced Java teams prefer extending RuntimeException for business errors.

Example

public class PaymentNotFoundException
extends RuntimeException {
    public PaymentNotFoundException(String message) {
super(message);
}
}

Reasons

  • Cleaner service layer
  • No unnecessary throws declarations
  • Business failures are usually not recoverable by callers
  • Avoids excessive try-catch blocks
  • Keeps APIs easier to read

Use checked exceptions only when the caller is expected to recover, such as file I/O or network operations.

Common Interview Questions

What is the difference between Error and Exception?

Errors indicate serious JVM failures and are generally unrecoverable. Exceptions represent application-level problems that can often be handled.

Difference between throw and throws?

throw is used to explicitly throw an exception inside a method, whereas throws declares that a method may pass an exception to its caller.

Checked vs Unchecked Exception?

Checked exceptions are verified at compile time and must be handled or declared. Unchecked exceptions occur at runtime and handling them is optional.

Why use @RestControllerAdvice?

It centralizes exception handling across the application, reducing duplicate code and ensuring consistent API responses.

Why use custom exceptions?

They make business logic more expressive, improve debugging, and provide meaningful error messages for clients.

Final Thoughts

Exception handling isn’t just about preventing application crashes — it’s about building software that fails gracefully, communicates clearly, and remains maintainable as it grows.

A well-designed exception strategy should:

  • Separate business errors from system failures.
  • Use custom exceptions to express domain rules.
  • Centralize handling with @RestControllerAdvice.
  • Return consistent, structured API responses.
  • Log errors effectively without exposing internal details.
  • Use appropriate HTTP status codes for REST APIs.

Mastering exception handling is a hallmark of experienced Java and Spring Boot developers. It not only improves application reliability but also makes debugging, maintenance, and collaboration significantly easier — skills that matter both in production systems and technical interviews.

If you found this guide helpful, consider sharing it with your team and fellow Java developers. Clean exception handling leads to cleaner code, more resilient applications, and happier users.

--

--

Parmeshwar Pardeshi
Parmeshwar Pardeshi

Building scalable backend systems. Writing about Java, Spring Boot, AWS, Kafka, Microservices & interview preparation.