Handle Exceptions in SpingBoot REST API, TechPool

Hello everyone! Doing well in covid situations? I hope so...Today I brought you a very important article that will be useful while implementing REST APIs or Micro Services with SpringBoot

As we know handling errors/exceptions in applications is very critical. In case of any failure, we have to inform about the anomaly to the user. Otherwise, if we just say it is an "error", it's not going to be a help for anyone! We have to communicate why that error occurs and what was the root cause. Then troubleshooting or bug fixing will be more efficient than we think.

So, basically, I will be creating a REST API using SpringBoot to demonstrate how to catch exceptions thrown from your service layer. This API will follow the following structure.

  • controllers     - which accept the client requests
  • models           - which contains entity classes/POJOs
  • services         - which performs the logic to return data
  • repositories   - which handles data with database
  • exceptions     - which holds custom exception classes

Here I will only take one API endpoint. It will be fetching products by its ID. and explain how we are going to handle exceptions and send them to the controller layer for later use in front-end applications. 


Controller Layer

The controller is the main contact point for the client application. This is the place where we should communicate the response to the client(front-end). I have implemented the logic by auto wiring the service and using ResponseEntity class. API calling path is /api/products/id. Look at the below code.


Service Layer

Here we implement the logic usually to get data. So, what we should do, when the product is not found by ID? That's the case! We can throw an exception. It can be just a RuntimeException. But it's better to have a custom exception for this use case. In the next part, we will create that. The custom exception I'm using is ProductNotFoundException. Here, I have given the code for the service layer logic. ProdcutService is the interface and ProductServiceImpl has the implementation. ProductRepository is the DAO class that helps us the connect with database. I'm using a MongoDB database.


Exception Layer

Create Custom Exception

So, here we can define our own exception which should be thrown when the product is not found: 404 situations!

@ResponseStatus(HttpStatus.NOT_FOUND)
This line helps the application to identify when to throw the exception.

Let's try this implementation with Postman!


Just hit with an invalid ID that is not available in your database. There we can see the exception thrown! but its content is not leading us in a correct way. No message in it! So how do we inform the user about the error he/she has done using this response?

Throw Exceptions to the Controller

Spring provides a mechanism to deal with exceptions. It has an annotation called @ControllerAdvice. This is the guy that is going to help us guys!!!!

@ControllerAdvice is a specialization of the @Component annotation which allows handling exceptions across the whole application in one global handling component. So, DefaultExceptionHandler is the class responsible for resolving all the exceptions.
  • We are going to implement a separate Java class for this. Let's call it as DefaultExceptionHandler. This will be the global point for our exception-handling part. 
  • Like we use @RequestMapping annotation, we have to put this annotation at the top of the class name.
  • Since we are sending the response from the controller wrapped as ResponseEntity objects, we need to inherit this exception handler class from ResponseEntityExceptionHandler.
  • We need a POJO for the error message also. I have created that as ErrorMessage.

Look at the below code. Next, I will explain ErrorMessage POJO class.


So, I'm going to show you the ErrorMessage class now. Basically, I want to send the error with the below details. Ideally, these are the properties of the ErrorMessage class! It's just a class with the below data...
  • message
  • request method
  • request path
  • port

With this let's re-run the application now and try the same request URL in Postman.


NOTE:
You can clearly see there's one method for each Exception type inside the exception handler class, previously implemented. When a ProductNotFoundException is thrown, handleProductNotFoundException method will be called.

Now we get the message guys!!! But wait...From where do we get this message saying "message": "Product not found with id: 17" ??? I hope you remember the service layer logic! We have thrown a ProductNotFoundException when the product ID is not matched. If you don't remember, refer to the Service Layer code again! I'm pretty sure you will get it..

So now we are able to inform the user what's wrong with the request! The controller sends this message to the front-end. So, the front-end can have a logic to process the response and show the error as an alert! This is the real advantage of proper exception handling in SpringBoot.

I hope you got something new today! This is a very tricky point while dealing with exceptions guys! You can define your own exceptions with predefined status codes like 404, 304, 500 like I did for the 404 situations in DefaultExceptionHandler class. 

So, try this and let me know your ideas also. Goodbye!

7 Comments

  1. Thank you so much for this nice valuable information.

    ReplyDelete
  2. If you're looking for the best Dell service center in Indirapuram, Ghaziabad, then you've come to the right place. This service center is able to fix a variety of laptop problems, including flickering, white screens, and more. In addition, they can help you upgrade your system for a fraction of the cost of a new Dell. If you have any questions about the service center, contact them by phone at 7042640351
    Dell Service Center Indirapuram

    ReplyDelete
  3. thank you for this valuable information. keep posting more.. waiting for more updates.
    Find pdf | pdf search engine

    ReplyDelete
  4. Please share a code of a best forum section. I want to use it for my website.

    ReplyDelete