From 2f92121ece52800627efbb493c6b6f292c26b099 Mon Sep 17 00:00:00 2001 From: Haider Iqbal Date: Thu, 12 Sep 2024 12:21:24 +0100 Subject: [PATCH] - Add Custom Exception Handler (#737) --- .../api/exception/BadRequestException.java | 7 ++++ .../api/exception/CustomErrorController.java | 38 +++++++++++++++++ .../api/exception/ErrorResponse.java | 16 ++++++++ .../api/exception/GlobalExceptionHandler.java | 41 +++++++++++++++++++ .../exception/ResourceNotFoundException.java | 7 ++++ .../src/main/resources/application.properties | 7 +++- 6 files changed, 115 insertions(+), 1 deletion(-) create mode 100644 backend/src/main/java/uk/ac/ebi/spot/ols/controller/api/exception/BadRequestException.java create mode 100644 backend/src/main/java/uk/ac/ebi/spot/ols/controller/api/exception/CustomErrorController.java create mode 100644 backend/src/main/java/uk/ac/ebi/spot/ols/controller/api/exception/ErrorResponse.java create mode 100644 backend/src/main/java/uk/ac/ebi/spot/ols/controller/api/exception/GlobalExceptionHandler.java create mode 100644 backend/src/main/java/uk/ac/ebi/spot/ols/controller/api/exception/ResourceNotFoundException.java diff --git a/backend/src/main/java/uk/ac/ebi/spot/ols/controller/api/exception/BadRequestException.java b/backend/src/main/java/uk/ac/ebi/spot/ols/controller/api/exception/BadRequestException.java new file mode 100644 index 000000000..77ea62ed9 --- /dev/null +++ b/backend/src/main/java/uk/ac/ebi/spot/ols/controller/api/exception/BadRequestException.java @@ -0,0 +1,7 @@ +package uk.ac.ebi.spot.ols.controller.api.exception; + +public class BadRequestException extends RuntimeException { + public BadRequestException(String message) { + super(message); + } +} \ No newline at end of file diff --git a/backend/src/main/java/uk/ac/ebi/spot/ols/controller/api/exception/CustomErrorController.java b/backend/src/main/java/uk/ac/ebi/spot/ols/controller/api/exception/CustomErrorController.java new file mode 100644 index 000000000..ac2d17514 --- /dev/null +++ b/backend/src/main/java/uk/ac/ebi/spot/ols/controller/api/exception/CustomErrorController.java @@ -0,0 +1,38 @@ +package uk.ac.ebi.spot.ols.controller.api.exception; + +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.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; + +import javax.servlet.http.HttpServletRequest; + +@RestController +public class CustomErrorController implements ErrorController { + + @RequestMapping(value = "/error", produces = MediaType.APPLICATION_JSON_VALUE) + @ResponseBody + public ResponseEntity handleError(HttpServletRequest request) { + Integer statusCode = (Integer) request.getAttribute("javax.servlet.error.status_code"); + Exception exception = (Exception) request.getAttribute("javax.servlet.error.exception"); + + if (statusCode == null) { + statusCode = HttpStatus.INTERNAL_SERVER_ERROR.value(); + } + + String errorMessage = "An unexpected error occurred"; + if (exception != null) { + errorMessage = exception.getMessage(); + } else if (statusCode == HttpStatus.NOT_FOUND.value()) { + errorMessage = "The requested resource was not found"; + } + + ErrorResponse errorResponse = new ErrorResponse(statusCode, errorMessage); + return ResponseEntity.status(statusCode) + .contentType(MediaType.APPLICATION_JSON) + .body(errorResponse); + } +} \ No newline at end of file diff --git a/backend/src/main/java/uk/ac/ebi/spot/ols/controller/api/exception/ErrorResponse.java b/backend/src/main/java/uk/ac/ebi/spot/ols/controller/api/exception/ErrorResponse.java new file mode 100644 index 000000000..acb968a6c --- /dev/null +++ b/backend/src/main/java/uk/ac/ebi/spot/ols/controller/api/exception/ErrorResponse.java @@ -0,0 +1,16 @@ +package uk.ac.ebi.spot.ols.controller.api.exception; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public class ErrorResponse { + @JsonProperty("status") + private int http_status; + + @JsonProperty("message") + private String message; + + public ErrorResponse(int http_status, String message) { + this.http_status = http_status; + this.message = message; + } +} diff --git a/backend/src/main/java/uk/ac/ebi/spot/ols/controller/api/exception/GlobalExceptionHandler.java b/backend/src/main/java/uk/ac/ebi/spot/ols/controller/api/exception/GlobalExceptionHandler.java new file mode 100644 index 000000000..197de4dd3 --- /dev/null +++ b/backend/src/main/java/uk/ac/ebi/spot/ols/controller/api/exception/GlobalExceptionHandler.java @@ -0,0 +1,41 @@ +package uk.ac.ebi.spot.ols.controller.api.exception; + +import org.springframework.core.Ordered; +import org.springframework.core.annotation.Order; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.servlet.NoHandlerFoundException; + +@ControllerAdvice +@Order(Ordered.HIGHEST_PRECEDENCE) +public class GlobalExceptionHandler { + + @ExceptionHandler(NoHandlerFoundException.class) + @ResponseBody + public ResponseEntity handleNoHandlerFoundException(NoHandlerFoundException ex) { + ErrorResponse error = new ErrorResponse(HttpStatus.NOT_FOUND.value(), "Endpoint not found: " + ex.getRequestURL()); + return ResponseEntity.status(HttpStatus.NOT_FOUND) + .contentType(MediaType.APPLICATION_JSON) + .body(error); + } + + @ExceptionHandler(Exception.class) + @ResponseBody + public ResponseEntity handleAllExceptions(Exception ex) { + HttpStatus status = HttpStatus.INTERNAL_SERVER_ERROR; + if (ex instanceof ResourceNotFoundException) { + status = HttpStatus.NOT_FOUND; + } else if (ex instanceof BadRequestException) { + status = HttpStatus.BAD_REQUEST; + } + + ErrorResponse error = new ErrorResponse(status.value(), ex.getMessage()); + return ResponseEntity.status(status) + .contentType(MediaType.APPLICATION_JSON) + .body(error); + } +} \ No newline at end of file diff --git a/backend/src/main/java/uk/ac/ebi/spot/ols/controller/api/exception/ResourceNotFoundException.java b/backend/src/main/java/uk/ac/ebi/spot/ols/controller/api/exception/ResourceNotFoundException.java new file mode 100644 index 000000000..f3f2906e5 --- /dev/null +++ b/backend/src/main/java/uk/ac/ebi/spot/ols/controller/api/exception/ResourceNotFoundException.java @@ -0,0 +1,7 @@ +package uk.ac.ebi.spot.ols.controller.api.exception; + +public class ResourceNotFoundException extends RuntimeException { + public ResourceNotFoundException(String message) { + super(message); + } +} diff --git a/backend/src/main/resources/application.properties b/backend/src/main/resources/application.properties index 022080ffb..6e85d0e17 100644 --- a/backend/src/main/resources/application.properties +++ b/backend/src/main/resources/application.properties @@ -2,4 +2,9 @@ spring.jackson.serialization.INDENT_OUTPUT=true springdoc.swagger-ui.path=/swagger-ui-ols4.html springdoc.swagger-ui.operationsSorter=method -springdoc.swagger-ui.disable-swagger-default-url=true \ No newline at end of file +springdoc.swagger-ui.disable-swagger-default-url=true + +spring.mvc.throw-exception-if-no-handler-found=true +spring.web.resources.add-mappings=false + +server.error.whitelabel.enabled=false \ No newline at end of file