0
0
Spring Bootframework~15 mins

Handling not found exceptions in Spring Boot - Deep Dive

Choose your learning style9 modes available
Overview - Handling not found exceptions
What is it?
Handling not found exceptions means managing cases when a requested resource or data is missing in a Spring Boot application. Instead of letting the app crash or return confusing errors, it catches these situations and responds clearly. This helps users and developers understand that something was not found, like a missing user or product. It improves the app's reliability and user experience.
Why it matters
Without handling not found exceptions, users might see unclear errors or server crashes when they request missing data. This leads to frustration and confusion. Proper handling ensures the app gracefully informs users about missing resources, making the app feel professional and trustworthy. It also helps developers debug and maintain the app more easily.
Where it fits
Before learning this, you should understand basic Spring Boot controllers and exception handling. After this, you can learn about global exception handling, custom error responses, and advanced error logging. This topic fits into building robust REST APIs and user-friendly web applications.
Mental Model
Core Idea
Handling not found exceptions means catching missing data requests early and responding with clear, user-friendly messages instead of errors or crashes.
Think of it like...
It's like a store clerk who, when asked for an item that's out of stock, politely tells you it's unavailable instead of ignoring you or giving a confusing answer.
┌───────────────┐
│ Client Request│
└──────┬────────┘
       │
       ▼
┌───────────────┐
│ Controller    │
│ (find resource)│
└──────┬────────┘
       │
       ▼
┌───────────────┐        ┌─────────────────────┐
│ Resource Found│───────▶│ Return data (200 OK) │
└───────────────┘        └─────────────────────┘
       │
       ▼
┌───────────────┐        ┌─────────────────────────────┐
│ Resource NOT  │───────▶│ Throw NotFoundException      │
│ Found         │        └─────────────────────────────┘
       │
       ▼
┌───────────────┐        ┌─────────────────────────────┐
│ Exception    │◀───────│ Exception Handler catches it│
│ Handler      │        │ and returns 404 Not Found    │
└───────────────┘        └─────────────────────────────┘
Build-Up - 7 Steps
1
FoundationWhat is a Not Found Exception
🤔
Concept: Introduce the idea of a not found exception as a signal that requested data does not exist.
In Spring Boot, when you ask for data by ID or name, sometimes it doesn't exist. For example, looking for a user with ID 5 when only users 1-4 exist. This situation is called 'not found'. Spring Boot can throw a special exception to say 'I couldn't find it'.
Result
You understand that not found exceptions represent missing data situations in your app.
Understanding what 'not found' means helps you see why special handling is needed instead of letting the app fail silently or crash.
2
FoundationBasic Exception Handling in Spring Boot
🤔
Concept: Learn how Spring Boot handles exceptions by default and how to catch them in controllers.
By default, if an exception happens in a controller, Spring Boot returns a generic error page or JSON with status 500. You can catch exceptions using try-catch blocks or by defining methods annotated with @ExceptionHandler inside your controller to handle specific exceptions.
Result
You can catch exceptions locally and return custom responses instead of default errors.
Knowing how to catch exceptions locally is the first step to controlling error responses and improving user experience.
3
IntermediateCreating a Custom NotFoundException Class
🤔Before reading on: do you think you can use a built-in exception for 'not found' or should you create a custom one? Commit to your answer.
Concept: Introduce creating a custom exception class to represent not found errors clearly.
Spring Boot does not have a built-in NotFoundException for your app's domain. You create your own class extending RuntimeException, for example: public class NotFoundException extends RuntimeException { public NotFoundException(String message) { super(message); } } Throw this exception when data is missing.
Result
You have a clear, reusable way to signal missing data in your app.
Creating a custom exception makes your code clearer and separates error types, which helps in handling them specifically.
4
IntermediateUsing @ExceptionHandler for Local Handling
🤔Before reading on: do you think @ExceptionHandler methods can handle exceptions thrown anywhere in the app or only inside the controller? Commit to your answer.
Concept: Learn how to use @ExceptionHandler in a controller to catch NotFoundException and return a 404 response.
Inside your controller, add a method: @ExceptionHandler(NotFoundException.class) public ResponseEntity handleNotFound(NotFoundException ex) { return ResponseEntity.status(HttpStatus.NOT_FOUND).body(ex.getMessage()); } When NotFoundException is thrown in this controller, this method sends a 404 status with a message.
Result
Your controller returns a clear 404 response instead of a generic error.
Using @ExceptionHandler locally lets you customize error responses per controller, improving clarity and user feedback.
5
IntermediateThrowing NotFoundException in Service Layer
🤔
Concept: Learn to throw NotFoundException from service methods when data is missing.
In your service class, when you look for data, check if it exists. If not, throw NotFoundException: public User getUserById(Long id) { return userRepository.findById(id) .orElseThrow(() -> new NotFoundException("User not found with id " + id)); } This cleanly signals missing data to the controller.
Result
Your service layer clearly communicates missing data by throwing exceptions.
Throwing exceptions in the service layer separates business logic from error handling, making code cleaner and easier to maintain.
6
AdvancedGlobal Exception Handling with @ControllerAdvice
🤔Before reading on: do you think @ExceptionHandler methods in controllers handle exceptions from all controllers or only their own? Commit to your answer.
Concept: Learn to handle exceptions globally for the whole app using @ControllerAdvice.
Create a class annotated with @ControllerAdvice: @ControllerAdvice public class GlobalExceptionHandler { @ExceptionHandler(NotFoundException.class) public ResponseEntity handleNotFoundGlobally(NotFoundException ex) { return ResponseEntity.status(HttpStatus.NOT_FOUND).body(ex.getMessage()); } } This catches NotFoundException from any controller and returns 404.
Result
Your app has a single place to handle not found errors, reducing repetition.
Global handling centralizes error responses, making maintenance easier and ensuring consistent user experience.
7
ExpertCustomizing Error Response Body Structure
🤔Before reading on: do you think returning just a string message is enough for APIs or should error responses be structured? Commit to your answer.
Concept: Learn to create detailed error responses with JSON containing status, message, timestamp, and path.
Define an error response class: public class ApiError { private int status; private String message; private LocalDateTime timestamp; private String path; // constructors, getters } In your global handler: @ExceptionHandler(NotFoundException.class) public ResponseEntity handleNotFoundDetailed(NotFoundException ex, HttpServletRequest req) { ApiError error = new ApiError(404, ex.getMessage(), LocalDateTime.now(), req.getRequestURI()); return ResponseEntity.status(HttpStatus.NOT_FOUND).body(error); } This gives clients more info to handle errors.
Result
Your API returns rich error details improving client debugging and user messages.
Structured error responses are essential for professional APIs, enabling better client-side handling and monitoring.
Under the Hood
When a controller method throws NotFoundException, Spring Boot's DispatcherServlet catches it during request processing. It looks for @ExceptionHandler methods matching the exception type, first in the controller, then in any @ControllerAdvice classes. The matching handler method is invoked to build a ResponseEntity with status 404 and a body. This response is sent back to the client instead of a generic error page. This mechanism uses Spring's HandlerExceptionResolver chain internally.
Why designed this way?
Spring Boot separates normal request handling from error handling to keep code clean and modular. Using annotations like @ExceptionHandler and @ControllerAdvice allows developers to define error responses declaratively and reuse them globally or locally. This design avoids cluttering business logic with error code and supports consistent error handling across large apps.
┌───────────────────────────────┐
│ Client sends HTTP request      │
└───────────────┬───────────────┘
                │
                ▼
┌───────────────────────────────┐
│ DispatcherServlet routes to    │
│ Controller method              │
└───────────────┬───────────────┘
                │
                ▼
┌───────────────────────────────┐
│ Controller method executes     │
│ Throws NotFoundException       │
└───────────────┬───────────────┘
                │
                ▼
┌───────────────────────────────┐
│ DispatcherServlet catches      │
│ exception, looks for handler   │
│ @ExceptionHandler or @ControllerAdvice
└───────────────┬───────────────┘
                │
                ▼
┌───────────────────────────────┐
│ Handler method builds Response │
│ with 404 status and message    │
└───────────────┬───────────────┘
                │
                ▼
┌───────────────────────────────┐
│ Response sent back to client   │
└───────────────────────────────┘
Myth Busters - 4 Common Misconceptions
Quick: Does throwing NotFoundException automatically return a 404 HTTP status? Commit to yes or no.
Common Belief:Throwing NotFoundException automatically sends a 404 Not Found HTTP response.
Tap to reveal reality
Reality:Throwing the exception alone does not set the HTTP status. You must handle it with @ExceptionHandler or @ControllerAdvice to return 404.
Why it matters:Without proper handling, the client gets a 500 Internal Server Error instead of 404, causing confusion and wrong error reporting.
Quick: Can @ExceptionHandler methods in one controller handle exceptions from other controllers? Commit to yes or no.
Common Belief:@ExceptionHandler methods in a controller catch exceptions from all controllers globally.
Tap to reveal reality
Reality:@ExceptionHandler methods inside a controller only handle exceptions thrown within that controller. For global handling, use @ControllerAdvice.
Why it matters:Misunderstanding this leads to missing error handling in other parts of the app and inconsistent responses.
Quick: Is returning a plain string message enough for API error responses? Commit to yes or no.
Common Belief:A simple string message is sufficient for error responses in APIs.
Tap to reveal reality
Reality:Structured JSON error responses with status, message, timestamp, and path provide better information for clients and debugging.
Why it matters:Poorly structured errors make client-side error handling and monitoring harder, reducing API usability.
Quick: Does Spring Boot automatically convert any RuntimeException to a JSON error response? Commit to yes or no.
Common Belief:Spring Boot automatically converts all RuntimeExceptions to JSON error responses.
Tap to reveal reality
Reality:Only exceptions handled by @ExceptionHandler or default error handling produce JSON responses. Others may cause HTML error pages or server errors.
Why it matters:Assuming automatic JSON conversion can cause unexpected error formats and break API clients.
Expert Zone
1
Using @ResponseStatus on custom exceptions can simplify handlers by automatically setting HTTP status without explicit ResponseEntity.
2
Exception handler methods can accept HttpServletRequest or WebRequest parameters to add request details to error responses.
3
Stack trace logging in exception handlers should be balanced to avoid performance issues and sensitive data leaks.
When NOT to use
Handling not found exceptions with thrown exceptions is not ideal for very high-performance or streaming APIs where exceptions are costly. Alternatives include returning Optional or special result objects and handling missing data without exceptions.
Production Patterns
In production, global exception handlers with structured JSON error responses are standard. Many apps include error codes, user-friendly messages, and correlation IDs for tracing. Logging frameworks integrate with handlers to capture errors centrally.
Connections
HTTP Status Codes
Handling not found exceptions maps directly to using HTTP 404 status codes.
Understanding HTTP status codes helps you design meaningful error responses that clients and browsers understand.
REST API Design
Proper exception handling is a key part of designing clean, predictable REST APIs.
Knowing how to handle errors gracefully improves API usability and developer experience.
Customer Service Communication
Handling not found exceptions is like customer service politely informing customers when a product is unavailable.
This connection shows how clear communication in software mirrors good human interactions, improving satisfaction.
Common Pitfalls
#1Throwing NotFoundException but not handling it results in generic 500 errors.
Wrong approach:public User getUser(Long id) { if (user == null) throw new NotFoundException("User missing"); } // No @ExceptionHandler or @ControllerAdvice defined
Correct approach:@ControllerAdvice public class GlobalHandler { @ExceptionHandler(NotFoundException.class) public ResponseEntity handleNotFound(NotFoundException ex) { return ResponseEntity.status(HttpStatus.NOT_FOUND).body(ex.getMessage()); } }
Root cause:Not understanding that throwing exceptions alone does not control HTTP responses.
#2Using @ExceptionHandler in one controller expecting global effect.
Wrong approach:@RestController public class UserController { @ExceptionHandler(NotFoundException.class) public ResponseEntity handleNotFound(NotFoundException ex) { return ResponseEntity.status(HttpStatus.NOT_FOUND).body(ex.getMessage()); } } // Other controllers throw NotFoundException but no global handler
Correct approach:@ControllerAdvice public class GlobalExceptionHandler { @ExceptionHandler(NotFoundException.class) public ResponseEntity handleNotFoundGlobally(NotFoundException ex) { return ResponseEntity.status(HttpStatus.NOT_FOUND).body(ex.getMessage()); } }
Root cause:Misunderstanding scope of @ExceptionHandler methods.
#3Returning plain string error messages without structure.
Wrong approach:@ExceptionHandler(NotFoundException.class) public ResponseEntity handle(NotFoundException ex) { return ResponseEntity.status(HttpStatus.NOT_FOUND).body("Not found"); }
Correct approach:public class ApiError { private int status; private String message; private LocalDateTime timestamp; private String path; // getters, setters } @ExceptionHandler(NotFoundException.class) public ResponseEntity handleDetailed(NotFoundException ex, HttpServletRequest req) { ApiError error = new ApiError(404, ex.getMessage(), LocalDateTime.now(), req.getRequestURI()); return ResponseEntity.status(HttpStatus.NOT_FOUND).body(error); }
Root cause:Not realizing clients benefit from structured error information.
Key Takeaways
Handling not found exceptions means catching missing data requests and responding with clear 404 errors instead of crashes.
Creating custom exceptions and using @ExceptionHandler or @ControllerAdvice lets you control error responses locally or globally.
Throwing exceptions in the service layer separates business logic from error handling, making code cleaner.
Structured error responses with status, message, timestamp, and path improve API usability and debugging.
Understanding Spring Boot's exception handling flow helps avoid common mistakes and build robust applications.