99% of Java Developers Handle Exceptions Wrong — Here’s the Right Way
“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.
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 zeroThe JVM stops the normal execution because the exception wasn’t handled.
Exception Hierarchy
Object
|
Throwable
/ \
Error Exception
|
RuntimeExceptionUnderstanding 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
OutOfMemoryErrorException
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 FileNotFoundExceptionSolution
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
NullPointerExceptionTry-Catch
The simplest way to handle exceptions.
try{
int result = 10 / 0;
}catch(ArithmeticException ex){
System.out.println(ex.getMessage());
}Output
/ by zeroMultiple 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 nullMulti-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
CleanupTypical 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 nullGlobal Handler
@ExceptionHandler(
MethodArgumentNotValidException.class
)Return meaningful validation messages.
Standard Error Response
Instead of
Payment Not FoundReturn
{
"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 ResponseHTTP 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
throwsdeclarations - 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.









