ControllerExceptionHandler.java

package se.jobtechdev.personaldatagateway.api.controller;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.http.HttpServletRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.web.servlet.error.ErrorController;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
import se.jobtechdev.personaldatagateway.api.exception.ApiException;
import se.jobtechdev.personaldatagateway.api.util.ProblemDetailsFactory;
import se.jobtechdev.personaldatagateway.api.util.ResponseEntityFactory;

@RestController
@RestControllerAdvice
public class ControllerExceptionHandler extends ResponseEntityExceptionHandler
    implements ErrorController {
  private static final Logger log = LoggerFactory.getLogger(ControllerExceptionHandler.class);

  @ExceptionHandler(ApiException.class)
  public ResponseEntity<Object> exception(HttpServletRequest ignoredRequest, ApiException e) {
    log.debug("Encountered exception", e);
    final var objectMapper = new ObjectMapper();
    try {
      final var errorResponse = e.getProblemDetails();
      return ResponseEntity.status(errorResponse.getStatus())
          .contentType(MediaType.APPLICATION_JSON)
          .body(objectMapper.writeValueAsString(errorResponse));
    } catch (JsonProcessingException ex) {
      log.error(
          "Unexpected JsonProcessingException occurred: {} {}",
          e.getClass().getName(),
          e.getMessage());
      return ResponseEntity.status(500)
          .contentType(MediaType.APPLICATION_JSON)
          .body(
              "{\"status\":500,\"error\":\"Internal Server Error\",\"message\":\"Unexpected"
                  + " exception occurred\"}");
    }
  }

  @ExceptionHandler(Exception.class)
  public ResponseEntity<Object> exception(HttpServletRequest ignoredRequest, Exception e) {
    log.error("Encountered exception", e);
    final var errorResponse =
        ProblemDetailsFactory.createProblemDetails(
            HttpStatus.INTERNAL_SERVER_ERROR, "Unexpected exception occurred");
    return ResponseEntityFactory.create(errorResponse);
  }

  @GetMapping(path = "/error")
  public ResponseEntity<Object> errorHandler() {
    final var errorResponse =
        ProblemDetailsFactory.createProblemDetails(HttpStatus.NOT_FOUND, "Not found");
    return ResponseEntityFactory.create(errorResponse);
  }
}