Bird
Raised Fist0
Spring Bootframework~15 mins

Handling not found exceptions in Spring Boot - Deep Dive

Choose your learning style10 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.

Practice

(1/5)
1. What is the main purpose of handling not found exceptions in a Spring Boot application?
easy
A. To improve database performance
B. To log all user activities
C. To automatically retry failed requests
D. To return a clear 404 status when a requested resource is missing

Solution

  1. Step 1: Understand the role of not found exceptions

    Not found exceptions indicate that a requested resource does not exist on the server.
  2. Step 2: Identify the correct response behavior

    Returning a 404 HTTP status code clearly informs the client that the resource is missing.
  3. Final Answer:

    To return a clear 404 status when a requested resource is missing -> Option D
  4. Quick Check:

    Not found exceptions = 404 status [OK]
Hint: Not found means resource missing, so send 404 status [OK]
Common Mistakes:
  • Confusing not found with server errors
  • Thinking it improves database speed
  • Assuming it retries requests automatically
2. Which annotation is used in Spring Boot to mark a custom exception class to return HTTP 404 status automatically?
easy
A. @ResponseStatus(HttpStatus.NOT_FOUND)
B. @ExceptionHandler(HttpStatus.NOT_FOUND)
C. @NotFoundException
D. @HttpStatusCode(404)

Solution

  1. Step 1: Recall Spring Boot annotations for HTTP status

    The @ResponseStatus annotation sets the HTTP status code for exceptions or controller methods.
  2. Step 2: Match the annotation to 404 status

    Using @ResponseStatus(HttpStatus.NOT_FOUND) on a custom exception class sends 404 automatically.
  3. Final Answer:

    @ResponseStatus(HttpStatus.NOT_FOUND) -> Option A
  4. Quick Check:

    @ResponseStatus + NOT_FOUND = 404 [OK]
Hint: Use @ResponseStatus with NOT_FOUND for 404 exceptions [OK]
Common Mistakes:
  • Using @ExceptionHandler instead of @ResponseStatus
  • Assuming @NotFoundException is a valid annotation
  • Using incorrect annotation names
3. Given this controller method in Spring Boot:
 @GetMapping("/items/{id}")
 public Item getItem(@PathVariable Long id) {
     return itemRepository.findById(id)
         .orElseThrow(() -> new ItemNotFoundException(id));
 }

What happens if the item with the given id does not exist?
medium
A. The method returns null and HTTP 200 status
B. An ItemNotFoundException is thrown and HTTP 404 status is returned
C. The server crashes with a NullPointerException
D. The method returns an empty Item object

Solution

  1. Step 1: Analyze the use of orElseThrow

    If the item is not found, orElseThrow triggers the custom ItemNotFoundException.
  2. Step 2: Understand exception handling with @ResponseStatus

    If ItemNotFoundException is annotated with @ResponseStatus(HttpStatus.NOT_FOUND), Spring returns 404 status.
  3. Final Answer:

    An ItemNotFoundException is thrown and HTTP 404 status is returned -> Option B
  4. Quick Check:

    orElseThrow + @ResponseStatus = 404 error [OK]
Hint: orElseThrow triggers exception, annotated exception sends 404 [OK]
Common Mistakes:
  • Assuming null is returned instead of exception
  • Confusing 404 with 500 server error
  • Thinking empty object is returned
4. Consider this code snippet:
 @ResponseStatus(HttpStatus.NOT_FOUND)
 public class ProductNotFoundException extends RuntimeException {
     public ProductNotFoundException(Long id) {
         super("Product " + id + " not found");
     }
 }

 @GetMapping("/products/{id}")
 public Product getProduct(@PathVariable Long id) {
     return productRepo.findById(id).orElseThrow(() -> new ProductNotFoundException(id));
 }

What is the likely problem if the client always receives HTTP 500 instead of 404 when a product is missing?
medium
A. The exception is thrown but Spring does not map it to 404
B. The exception is not annotated with @ResponseStatus
C. The controller method does not handle the exception explicitly
D. The exception class is missing a no-argument constructor

Solution

  1. Step 1: Verify annotation presence

    The exception class is correctly annotated with @ResponseStatus(HttpStatus.NOT_FOUND).
  2. Step 2: Understand Spring's exception mapping

    If Spring returns 500, it means it does not recognize the exception mapping to 404, possibly due to package scanning or configuration issues.
  3. Final Answer:

    The exception is thrown but Spring does not map it to 404 -> Option A
  4. Quick Check:

    Annotated exception but 500 means mapping failed [OK]
Hint: 500 instead of 404 means Spring missed exception mapping [OK]
Common Mistakes:
  • Assuming missing no-arg constructor causes 500
  • Thinking @ResponseStatus is missing when it is present
  • Believing explicit handler is always required
5. You want to create a global exception handler in Spring Boot that returns a JSON error with 404 status and a message when any ResourceNotFoundException occurs. Which approach correctly achieves this?
hard
A. Use @RestController on the exception class and return 404 status
B. Annotate ResourceNotFoundException with @ResponseStatus(HttpStatus.NOT_FOUND) only, no handler needed
C. Create a class annotated with @ControllerAdvice and a method with @ExceptionHandler(ResourceNotFoundException.class) returning ResponseEntity with status 404 and error body
D. Throw ResponseStatusException with 404 inside every controller method manually

Solution

  1. Step 1: Understand global exception handling

    Using @ControllerAdvice with @ExceptionHandler allows centralized handling of exceptions across controllers.
  2. Step 2: Return ResponseEntity with 404 and JSON body

    The handler method can build a ResponseEntity with HttpStatus.NOT_FOUND and a JSON error message for clients.
  3. Final Answer:

    Create a class annotated with @ControllerAdvice and a method with @ExceptionHandler(ResourceNotFoundException.class) returning ResponseEntity with status 404 and error body -> Option C
  4. Quick Check:

    Global handler + ResponseEntity = custom 404 JSON [OK]
Hint: Use @ControllerAdvice + @ExceptionHandler for global JSON 404 [OK]
Common Mistakes:
  • Relying only on @ResponseStatus without custom JSON body
  • Annotating exception class as controller
  • Manually throwing exceptions in every method
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard