Skip to content
Snippets Groups Projects
Commit f0ab89c0 authored by evilimkova's avatar evilimkova
Browse files

Adding extended error handling

parent 84bc58f9
No related branches found
No related tags found
1 merge request!36M2 fix certificate
package org.fuseri.modulecertificate.exceptions; package org.fuseri.modulecertificate.exceptions;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Getter;
import lombok.ToString;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import java.time.Clock;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.List;
/** @Getter
* @author Michal Badin - Formula 1 team @ToString
*/ class ApiError {
public class ApiError {
private LocalDateTime timestamp;
private HttpStatus status; private HttpStatus status;
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "dd-MM-yyyy hh:mm:ss")
private LocalDateTime timestamp;
private String message; private String message;
private List<ApiSubError> subErrors;
private String path; private String path;
public ApiError(LocalDateTime timestamp, HttpStatus status, String message, String path) { private ApiError() {
this.timestamp = timestamp; timestamp = LocalDateTime.now(Clock.systemUTC());
this.status = status;
this.message = message;
this.path = path;
}
public LocalDateTime getTimestamp() {
return timestamp;
}
public void setTimestamp(LocalDateTime timestamp) {
this.timestamp = timestamp;
}
public HttpStatus getStatus() {
return status;
} }
public void setStatus(HttpStatus status) { ApiError(HttpStatus status, Throwable ex, String path) {
this();
this.status = status; this.status = status;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path; this.path = path;
this.message = ex.getLocalizedMessage();
} }
@Override ApiError(HttpStatus status, List<ApiSubError> subErrors, Throwable ex, String path) {
public String toString() { this();
return "ApiError{" + this.status = status;
"timestamp=" + timestamp + this.subErrors = subErrors;
", status=" + status + this.path = path;
", message='" + message + '\'' + this.message = ex.getLocalizedMessage();
", path='" + path + '\'' +
'}';
} }
} }
......
package org.fuseri.modulecertificate.exceptions;
public interface ApiSubError {
}
package org.fuseri.modulecertificate.exceptions;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.ToString;
@Data
@EqualsAndHashCode(callSuper = false)
@AllArgsConstructor
@Getter
@ToString
class ApiValidationError implements ApiSubError {
private String object;
private String field;
private Object rejectedValue;
private String message;
}
package org.fuseri.modulecertificate.exceptions;
/**
* @author Michal Badin - Formula 1 team
* modified by Ester Vilímková
*/
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.server.ResponseStatusException;
import org.springframework.web.util.UrlPathHelper;
import java.time.Clock;
import java.time.LocalDateTime;
@RestControllerAdvice
public class CustomRestGlobalExceptionHandling {
private static final UrlPathHelper URL_PATH_HELPER = new UrlPathHelper();
@ExceptionHandler({ResponseStatusException.class})
public ResponseEntity<ApiError> handleResponseStatus(
final ResponseStatusException ex, final HttpServletRequest request) {
final ApiError apiError = new ApiError(
LocalDateTime.now(Clock.systemUTC()),
HttpStatus.NOT_FOUND,
ex.getLocalizedMessage(),
URL_PATH_HELPER.getRequestUri(request));
return new ResponseEntity<>(apiError, new HttpHeaders(), apiError.getStatus());
}
/**
* Handle all the exceptions not matched by above-mentioned definitions.
*
* @param ex the ex
* @param request the request
* @return the response entity
*/
@ExceptionHandler({Exception.class})
public ResponseEntity<ApiError> handleAll(final Exception ex, HttpServletRequest request) {
final ApiError apiError = new ApiError(
LocalDateTime.now(Clock.systemUTC()),
HttpStatus.INTERNAL_SERVER_ERROR,
getInitialException(ex).getLocalizedMessage(),
URL_PATH_HELPER.getRequestUri(request));
return new ResponseEntity<>(apiError, new HttpHeaders(), apiError.getStatus());
}
private Exception getInitialException(Exception ex) {
while (ex.getCause() != null) {
ex = (Exception) ex.getCause();
}
return ex;
}
}
package org.fuseri.modulecertificate.exceptions;
import jakarta.persistence.EntityNotFoundException;
import jakarta.servlet.http.HttpServletRequest;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.util.UrlPathHelper;
import java.util.List;
@ControllerAdvice
public class RestResponseEntityExceptionHandler {
private static final UrlPathHelper URL_PATH_HELPER = new UrlPathHelper();
/**
* Handle ResourceNotFoundException exceptions
*
* @param ex exception
* @param request request
* @return response entity
*/
@ExceptionHandler(value = {EntityNotFoundException.class})
public ResponseEntity<ApiError> handleNotFoundError(EntityNotFoundException ex, HttpServletRequest request) {
ApiError error = new ApiError(
HttpStatus.NOT_FOUND,
ex,
URL_PATH_HELPER.getRequestUri(request));
return buildResponseEntity(error);
}
/**
* Handle Validation exceptions
*
* @param ex exception
* @param request request
* @return response entity
*/
@ExceptionHandler(value = {MethodArgumentNotValidException.class, HttpMessageNotReadableException.class})
public ResponseEntity<ApiError> handleValidationErrors(MethodArgumentNotValidException ex, HttpServletRequest request) {
List<ApiSubError> subErrors = ex.getBindingResult().getFieldErrors()
.stream()
.map(e -> (ApiSubError) new ApiValidationError(e.getObjectName(), e.getField(), e.getRejectedValue(), e.getDefaultMessage()))
.toList();
ApiError error = new ApiError(
HttpStatus.BAD_REQUEST,
subErrors,
ex,
URL_PATH_HELPER.getRequestUri(request));
return buildResponseEntity(error);
}
/**
* Handle exceptions not matched by above handler methods
*
* @param ex exception
* @param request request
* @return response entity
*/
@ExceptionHandler({Exception.class})
public ResponseEntity<ApiError> handleAll(final Exception ex, HttpServletRequest request) {
final ApiError error = new ApiError(
HttpStatus.INTERNAL_SERVER_ERROR,
ExceptionUtils.getRootCause(ex),
URL_PATH_HELPER.getRequestUri(request));
return buildResponseEntity(error);
}
private ResponseEntity<ApiError> buildResponseEntity(ApiError apiError) {
return new ResponseEntity<>(apiError, apiError.getStatus());
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment