Skip to content

Commit

Permalink
fix: Fixing OpenAPI documentation and implementing date and time deta…
Browse files Browse the repository at this point in the history
…ils in ProblemDetail.
  • Loading branch information
joaobertholino committed Nov 23, 2024
1 parent 1d4e6df commit 55b6870
Show file tree
Hide file tree
Showing 2 changed files with 144 additions and 142 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

package org.springframework.samples.petclinic.rest.advice;

import jakarta.servlet.http.HttpServletRequest;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.http.HttpStatus;
import org.springframework.http.ProblemDetail;
Expand All @@ -27,11 +28,13 @@
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import java.net.URI;
import java.time.LocalDateTime;

/**
* Global Exception handler for REST controllers.
* <p>
* This class handles exceptions thrown by REST controllers and returns
* appropriate HTTP responses to the client.
* This class handles exceptions thrown by REST controllers and returns appropriate HTTP responses to the client.
*
* @author Vitaliy Fedoriv
* @author Alexander Dudkin
Expand All @@ -40,63 +43,69 @@
public class ExceptionControllerAdvice {

/**
* Private method for constructing the {@link ProblemDetail} object passing the name and details of the exception class.
* Private method for constructing the {@link ProblemDetail} object passing the name and details of the exception
* class.
*
* @param ex Object referring to the thrown exception.
* @param ex Object referring to the thrown exception.
* @param status HTTP response status.
* @param url URL request.
*/
private ProblemDetail detailBuild(Exception ex, HttpStatus status) {
private ProblemDetail detailBuild(Exception ex, HttpStatus status, StringBuffer url) {
ProblemDetail detail = ProblemDetail.forStatus(status);
detail.setTitle(ex.getClass().getName());
detail.setType(URI.create(url.toString()));
detail.setTitle(ex.getClass().getSimpleName());
detail.setDetail(ex.getLocalizedMessage());
detail.setProperty("timestamp", LocalDateTime.now());
return detail;
}

/**
* Handles all general exceptions by returning a 500 Internal Server Error status with error details.
*
* @param e The {@link Exception} to be handled
* @param e The {@link Exception} to be handled
* @param request {@link HttpServletRequest} object referring to the current request.
* @return A {@link ResponseEntity} containing the error information and a 500 Internal Server Error status
*/
@ExceptionHandler(Exception.class)
@ResponseBody
public ResponseEntity<ProblemDetail> handleGeneralException(Exception e) {
public ResponseEntity<ProblemDetail> handleGeneralException(Exception e, HttpServletRequest request) {
HttpStatus status = HttpStatus.INTERNAL_SERVER_ERROR;
ProblemDetail detail = this.detailBuild(e, status);
ProblemDetail detail = this.detailBuild(e, status, request.getRequestURL());
return ResponseEntity.status(status).body(detail);
}

/**
* Handles {@link DataIntegrityViolationException} which typically indicates database constraint violations.
* This method returns a 404 Not Found status if an entity does not exist.
* Handles {@link DataIntegrityViolationException} which typically indicates database constraint violations. This
* method returns a 404 Not Found status if an entity does not exist.
*
* @param ex The {@link DataIntegrityViolationException} to be handled
* @param request {@link HttpServletRequest} object referring to the current request.
* @return A {@link ResponseEntity} containing the error information and a 404 Not Found status
*/
@ExceptionHandler(DataIntegrityViolationException.class)
@ResponseBody
public ResponseEntity<ProblemDetail> handleDataIntegrityViolationException(DataIntegrityViolationException ex) {
public ResponseEntity<ProblemDetail> handleDataIntegrityViolationException(DataIntegrityViolationException ex, HttpServletRequest request) {
HttpStatus status = HttpStatus.NOT_FOUND;
ProblemDetail detail = this.detailBuild(ex, status);
ProblemDetail detail = this.detailBuild(ex, status, request.getRequestURL());
return ResponseEntity.status(status).body(detail);
}

/**
* Handles exception thrown by Bean Validation on controller methods parameters
*
* @param ex The {@link MethodArgumentNotValidException} to be handled
*
* @param ex The {@link MethodArgumentNotValidException} to be handled
* @param request {@link HttpServletRequest} object referring to the current request.
* @return A {@link ResponseEntity} containing the error information and a 400 Bad Request status.
*/
@ExceptionHandler(MethodArgumentNotValidException.class)
@ResponseBody
public ResponseEntity<ProblemDetail> handleMethodArgumentNotValidException(MethodArgumentNotValidException ex) {
public ResponseEntity<ProblemDetail> handleMethodArgumentNotValidException(MethodArgumentNotValidException ex, HttpServletRequest request) {
HttpStatus status = HttpStatus.BAD_REQUEST;
BindingErrorsResponse errors = new BindingErrorsResponse();
BindingResult bindingResult = ex.getBindingResult();
if (bindingResult.hasErrors()) {
errors.addAllErrors(bindingResult);
ProblemDetail detail = this.detailBuild(ex, status);
ProblemDetail detail = this.detailBuild(ex, status, request.getRequestURL());
return ResponseEntity.status(status).body(detail);
}
return ResponseEntity.status(status).build();
Expand Down
Loading

0 comments on commit 55b6870

Please sign in to comment.