10 Spring Boot Exception Handling Interview Questions and Answers
Prepare for your interview with our guide on Spring Boot exception handling. Learn techniques to manage errors and improve application reliability.
Prepare for your interview with our guide on Spring Boot exception handling. Learn techniques to manage errors and improve application reliability.
Spring Boot is a powerful framework for building Java-based applications, offering a streamlined approach to configuration and deployment. Exception handling in Spring Boot is a critical aspect, ensuring that applications can gracefully manage errors and provide meaningful feedback to users. Mastering exception handling not only improves the robustness of your applications but also enhances user experience and system reliability.
This article delves into key concepts and techniques for effective exception handling in Spring Boot. By exploring these example questions and answers, you will gain a deeper understanding of how to manage exceptions efficiently, preparing you to tackle interview questions with confidence and demonstrate your expertise in this essential area.
@ExceptionHandler
annotation.The @ExceptionHandler
annotation in Spring Boot is used to manage exceptions within your application. It allows you to define a method that will be invoked when a specific exception is thrown, centralizing your error handling logic. This separation from the main business logic makes your code cleaner and easier to maintain.
Example:
@RestController public class MyController { @GetMapping("/example") public String exampleMethod() { if (true) { // Simulating an error condition throw new CustomException("An error occurred"); } return "Success"; } @ExceptionHandler(CustomException.class) public ResponseEntity<String> handleCustomException(CustomException ex) { return new ResponseEntity<>(ex.getMessage(), HttpStatus.BAD_REQUEST); } } public class CustomException extends RuntimeException { public CustomException(String message) { super(message); } }
In this example, when exampleMethod
throws a CustomException
, the handleCustomException
method is invoked, returning a ResponseEntity
with a custom error message and a BAD_REQUEST
status.
@ControllerAdvice
.Global exception handling in Spring Boot can be achieved using the @ControllerAdvice
annotation. This allows you to handle exceptions across the entire application in one component, centralizing your exception handling logic.
Example:
import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.context.request.WebRequest; @ControllerAdvice public class GlobalExceptionHandler { @ExceptionHandler(Exception.class) public ResponseEntity<?> handleGlobalException(Exception ex, WebRequest request) { String errorMessage = "An error occurred: " + ex.getMessage(); return new ResponseEntity<>(errorMessage, HttpStatus.INTERNAL_SERVER_ERROR); } }
In this example, the GlobalExceptionHandler
class is annotated with @ControllerAdvice
, making it a global exception handler. The handleGlobalException
method handles all exceptions of type Exception
, returning a ResponseEntity
with a custom error message and an HTTP status code.
To handle a specific custom exception and return a custom error response, create a custom exception class and a global exception handler using @ControllerAdvice
. Define a method annotated with @ExceptionHandler
to manage the custom exception.
Example:
// Custom Exception Class public class CustomException extends RuntimeException { public CustomException(String message) { super(message); } } // Custom Error Response Class public class ErrorResponse { private String message; private int status; public ErrorResponse(String message, int status) { this.message = message; this.status = status; } // Getters and Setters } // Global Exception Handler @ControllerAdvice public class GlobalExceptionHandler { @ExceptionHandler(CustomException.class) public ResponseEntity<ErrorResponse> handleCustomException(CustomException ex) { ErrorResponse errorResponse = new ErrorResponse(ex.getMessage(), HttpStatus.BAD_REQUEST.value()); return new ResponseEntity<>(errorResponse, HttpStatus.BAD_REQUEST); } }
MethodArgumentNotValidException
and return a detailed error message.To handle MethodArgumentNotValidException
and return a detailed error message, use @ControllerAdvice
and @ExceptionHandler
.
Example:
import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.validation.FieldError; import org.springframework.web.bind.MethodArgumentNotValidException; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import java.util.HashMap; import java.util.Map; @ControllerAdvice public class GlobalExceptionHandler { @ExceptionHandler(MethodArgumentNotValidException.class) public ResponseEntity<Map<String, String>> handleValidationExceptions(MethodArgumentNotValidException ex) { Map<String, String> errors = new HashMap<>(); ex.getBindingResult().getAllErrors().forEach((error) -> { String fieldName = ((FieldError) error).getField(); String errorMessage = error.getDefaultMessage(); errors.put(fieldName, errorMessage); }); return new ResponseEntity<>(errors, HttpStatus.BAD_REQUEST); } }
To log all exceptions globally, use @ControllerAdvice
and @ExceptionHandler
to centralize exception handling and logging.
Example:
import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.context.request.WebRequest; @ControllerAdvice public class GlobalExceptionHandler { private static final Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class); @ExceptionHandler(Exception.class) public ResponseEntity<String> handleAllExceptions(Exception ex, WebRequest request) { logger.error("Exception: ", ex); return new ResponseEntity<>("An error occurred", HttpStatus.INTERNAL_SERVER_ERROR); } }
In this example, the GlobalExceptionHandler
class logs exceptions and returns a generic error message with an HTTP 500 status code.
HttpMessageNotReadableException
and provide a user-friendly error message.To handle HttpMessageNotReadableException
and provide a user-friendly error message, use @ControllerAdvice
and @ExceptionHandler
.
Example:
import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.http.converter.HttpMessageNotReadableException; @ControllerAdvice public class GlobalExceptionHandler { @ExceptionHandler(HttpMessageNotReadableException.class) public ResponseEntity<String> handleHttpMessageNotReadableException(HttpMessageNotReadableException ex) { String errorMessage = "Invalid request message format"; return new ResponseEntity<>(errorMessage, HttpStatus.BAD_REQUEST); } }
To propagate an exception from the service layer to the controller layer and handle it, use custom exceptions and @ControllerAdvice
.
First, create a custom exception:
public class CustomServiceException extends RuntimeException { public CustomServiceException(String message) { super(message); } }
Throw this exception in the service layer:
@Service public class MyService { public void performService() { // Some logic if (someCondition) { throw new CustomServiceException("Service layer exception occurred"); } } }
Handle the exception in the controller layer:
@RestController @RequestMapping("/api") public class MyController { @Autowired private MyService myService; @GetMapping("/perform") public ResponseEntity<String> performAction() { myService.performService(); return ResponseEntity.ok("Action performed successfully"); } } @ControllerAdvice public class GlobalExceptionHandler { @ExceptionHandler(CustomServiceException.class) public ResponseEntity<String> handleCustomServiceException(CustomServiceException ex) { return new ResponseEntity<>(ex.getMessage(), HttpStatus.BAD_REQUEST); } }
ConstraintViolationException
and return a list of violated constraints.To handle ConstraintViolationException
and return a list of violated constraints, use @ControllerAdvice
and @ExceptionHandler
.
Example:
import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import javax.validation.ConstraintViolation; import javax.validation.ConstraintViolationException; import java.util.List; import java.util.stream.Collectors; @ControllerAdvice public class GlobalExceptionHandler { @ExceptionHandler(ConstraintViolationException.class) public ResponseEntity<List<String>> handleConstraintViolationException(ConstraintViolationException ex) { List<String> violations = ex.getConstraintViolations() .stream() .map(ConstraintViolation::getMessage) .collect(Collectors.toList()); return new ResponseEntity<>(violations, HttpStatus.BAD_REQUEST); } }
In this example, the method captures the ConstraintViolationException
, extracts the violation messages, and returns them as a list with a BAD_REQUEST
status.
To implement a custom error page for a specific HTTP status code, such as 404, create a custom ErrorController
and configure the application properties.
First, create a custom error page (e.g., error-404.html
) in the src/main/resources/templates
directory:
<!DOCTYPE html> <html> <head> <title>Page Not Found</title> </head> <body> <h1>404 - Page Not Found</h1> <p>The page you are looking for might have been removed, had its name changed, or is temporarily unavailable.</p> </body> </html>
Next, create a custom ErrorController
:
import org.springframework.boot.web.servlet.error.ErrorController; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import javax.servlet.http.HttpServletRequest; @Controller public class CustomErrorController implements ErrorController { @RequestMapping("/error") public String handleError(HttpServletRequest request) { Object status = request.getAttribute("javax.servlet.error.status_code"); if (status != null) { int statusCode = Integer.parseInt(status.toString()); if (statusCode == 404) { return "error-404"; } } return "error"; } @Override public String getErrorPath() { return "/error"; } }
Finally, configure the application properties:
server.error.whitelabel.enabled=false
Testing exception handling in Spring Boot applications involves simulating scenarios where exceptions are thrown and verifying the application’s response. Use Spring Boot’s testing framework with JUnit and Mockito.
Example:
@RestController public class MyController { @GetMapping("/test") public String testEndpoint() { if (true) { // Simulate an error condition throw new CustomException("Custom error occurred"); } return "Success"; } } @ResponseStatus(HttpStatus.BAD_REQUEST) class CustomException extends RuntimeException { public CustomException(String message) { super(message); } } @SpringBootTest @AutoConfigureMockMvc public class MyControllerTest { @Autowired private MockMvc mockMvc; @Test public void testCustomException() throws Exception { mockMvc.perform(get("/test")) .andExpect(status().isBadRequest()) .andExpect(result -> assertTrue(result.getResolvedException() instanceof CustomException)) .andExpect(result -> assertEquals("Custom error occurred", result.getResolvedException().getMessage())); } }