Commit 3030a1ce authored by Alex Segers's avatar Alex Segers

[AFP-91] 🥅 Create custom exceptions & advices (@asegers)

parent c863039c
package com.afp.ordermanagement.exception;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;
@ResponseStatus(value = HttpStatus.UNAUTHORIZED)
public class BadAccessTokenException extends RuntimeException {
public BadAccessTokenException() {
super("Invalid access token");
}
}
package com.afp.ordermanagement.exception;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.support.WebExchangeBindException;
import org.springframework.web.server.ServerWebExchange;
@ControllerAdvice
@RequiredArgsConstructor
public class ControllerExceptionAdvice {
@ExceptionHandler(BadAccessTokenException.class)
public ResponseEntity<ErrorResponse> handleBadAccessTokenException(RuntimeException exc, ServerWebExchange exchange) {
final HttpStatus status = HttpStatus.UNAUTHORIZED;
final ServerHttpRequest request = exchange.getRequest();
return new ResponseEntity<>(new ErrorResponse(
status.value(),
request.getPath().value(),
status.getReasonPhrase(),
exc.getMessage()
), status);
}
@ExceptionHandler(ResourceNotFoundException.class)
public ResponseEntity<ErrorResponse> handleEntityNotFoundException(RuntimeException exc, ServerWebExchange exchange) {
final HttpStatus status = HttpStatus.NOT_FOUND;
final ServerHttpRequest request = exchange.getRequest();
return new ResponseEntity<>(new ErrorResponse(
status.value(),
request.getPath().value(),
status.getReasonPhrase(),
exc.getMessage()
), status);
}
@ExceptionHandler(RuntimeException.class)
public ResponseEntity<ErrorResponse> handleRuntimeException(RuntimeException exc, ServerWebExchange exchange) {
final HttpStatus status = HttpStatus.INTERNAL_SERVER_ERROR;
final ServerHttpRequest request = exchange.getRequest();
return new ResponseEntity<>(new ErrorResponse(
status.value(),
request.getPath().value(),
status.getReasonPhrase(),
exc.getMessage()
), status);
}
@ExceptionHandler(WebExchangeBindException.class)
public ResponseEntity<ErrorResponse> webExchangeBindException(WebExchangeBindException exc, ServerWebExchange exchange) {
final HttpStatus status = exc.getStatus();
final ServerHttpRequest request = exchange.getRequest();
if (InvalidEntityResponse.isEntityValid(exc.getTarget())) {
return new ResponseEntity<>(new ErrorResponse(
status.value(),
request.getPath().value(),
status.getReasonPhrase(),
exc.getMessage()
), status);
}
return new ResponseEntity<>(new InvalidEntityResponse(
status.value(),
request.getPath().value(),
status.getReasonPhrase(),
"Validation failed",
exc.getTarget()
), status);
}
}
package com.afp.ordermanagement.exception;
import lombok.Data;
import lombok.RequiredArgsConstructor;
import java.time.Instant;
@Data
@RequiredArgsConstructor
public class ErrorResponse {
public final Integer status;
public final String path, error, message;
public String timestamp = Instant.now().toString();
}
package com.afp.ordermanagement.exception;
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class InvalidEntityResponse extends ErrorResponse {
public List<Map<String, String>> fieldErrors;
public InvalidEntityResponse(Integer status, String path, String type, String message, Object entity) {
super(status, path, type, message);
this.fieldErrors = InvalidEntityResponse.parseViolations(entity);
}
public static boolean isEntityValid(Object entity) {
return validator.validate(entity).isEmpty();
}
static private final Validator validator = Validation.buildDefaultValidatorFactory().getValidator();
static private List<Map<String, String>> parseViolations(Object entity) {
List<Map<String, String>> fieldErrors = new ArrayList<>();
for (ConstraintViolation<Object> cv : validator.validate(entity)) {
Map<String, String> errorMap = new HashMap<String, String>() {{
put("field", cv.getPropertyPath().toString());
put("message", cv.getMessage());
}};
fieldErrors.add(errorMap);
}
return fieldErrors;
}
}
package com.afp.ordermanagement.exception;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;
@ResponseStatus(value = HttpStatus.NOT_FOUND)
public class ResourceNotFoundException extends RuntimeException {
public ResourceNotFoundException() {
super("Resource not found");
}
public ResourceNotFoundException(String message) {
super(message);
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment