Introduction

Welcome! In our previous lesson, we delved into the intricacies of data validation within Spring Boot REST APIs. Today, we're addressing a vital aspect of building resilient APIs: error handling. Proper error handling ensures that users receive meaningful feedback and that your application does not expose unnecessary details when something goes wrong.

Understanding Error Handling in Spring Boot

Error handling in Spring Boot is critical for translating cryptic 500 Internal Server Error responses into more informative HTTP responses with appropriate status codes and messages. There are multiple approaches to handling errors in Spring Boot, each with its own use cases:

  • @ExceptionHandler: This annotation allows you to handle exceptions at the controller level, providing fine-grained control over error handling within individual controllers.
  • @ControllerAdvice: This annotation enables global exception handling across all controllers, promoting consistency and reusability of error handling logic throughout your application.
  • ResponseStatusException: This is a programmatic way to throw HTTP status exceptions directly from your code, making it easy to return specific HTTP status codes and messages from within your controller methods.

Let's explore each of these methods in more detail.

The Controller-Level @ExceptionHandler

The @ExceptionHandler annotation allows you to handle exceptions at the controller level. Here’s a code snippet demonstrating how to use it in Kotlin:

Using @ExceptionHandler at the controller level can lead to redundancy because if multiple controllers handle the same type of exception, you might duplicate error handling logic in each controller. This approach can also result in inconsistency, as different controllers may implement slightly varied handling for the same exception, causing users to receive different error responses for similar issues, leading to an inconsistent user experience.

Global Exception Handling with @ControllerAdvice

For a more centralized approach, Spring Boot offers @ControllerAdvice. This allows you to handle exceptions globally across all controllers:

@ControllerAdvice ensures consistency and reusability by centralizing error handling logic. However, it could make your error handling logic a bit less straightforward to track, especially for new developers joining the project.

Using ResponseStatusException

Another approach is using ResponseStatusException, a programmatic way to throw HTTP status exceptions directly from your code:

ResponseStatusException is simple and direct, which makes it easy to use for straightforward cases. However, it may not be as flexible or reusable as other approaches and requires explicit handling in the controller logic.

server.error.include-message Property

When you send a GET HTTP request to the /todos/invalid-id endpoint now, you'll notice that the response might look like this:

However, the message "Todo not found" that you specified isn't included. This is because the application property server.error.include-message is not set. By default, Spring doesn't return error messages to reduce the risk of exposing sensitive information.

To control whether the "message" field is included in error responses, you should set the server.error.include-message property in the application.yml file. This property supports three values:

  • always – The "message" field is always included in error responses.
  • never – The "message" field is never included in error responses.
  • on_param – The "message" field is included in error responses only if the request contains the parameter message=true. Otherwise, the response won't include the "message."

Here’s how you can configure application.yml to always include the message:

In the upcoming practice exercises, we'll set this property to always in the application.yml file to ensure the message is included in the response.

Rule of Thumb

Understanding where exceptions can happen and the scope of their impact can guide you in choosing the right error handling technique:

  • If an exception is specific to a method, use ResponseStatusException. This allows you to throw HTTP status exceptions directly from your code for straightforward case handling.
  • If an exception is specific to a controller, use @ExceptionHandler at the controller level. This approach is quick and easy for handling exceptions localized to a single controller.
  • If an exception can happen across multiple controllers, use @ControllerAdvice. This provides a centralized, reusable way to handle exceptions globally across all controllers.
Summary

We've covered essential error-handling techniques in Spring Boot, from @ExceptionHandler for controller-specific handling to @ControllerAdvice for global error management, and ResponseStatusException for in-code status handling. Each method has its strengths and is suited for different scenarios. Up next, you'll practice these concepts to ensure a solid understanding. Happy coding!

Sign up
Join the 1M+ learners on CodeSignal
Be a part of our community of 1M+ users who develop and demonstrate their skills on CodeSignal