@RestController
@RequestMapping("/product")
@AllArgsConstructor
public class ProductController {
public static final String TRACE = "trace";
@Value("${reflectoring.trace:false}")
private boolean printStackTrace;
private final ProductService productService;
@GetMapping("/{id}")
public Product getProduct(@PathVariable String id){
return productService.getProduct(id);
}
@PostMapping
public Product addProduct(@RequestBody @Valid ProductInput input){
return productService.addProduct(input);
}
@ExceptionHandler(NoSuchElementFoundException.class)
@ResponseStatus(HttpStatus.NOT_FOUND)
public ResponseEntity<ErrorResponse> handleItemNotFoundException(
NoSuchElementFoundException exception,
WebRequest request
){
log.error("Failed to find the requested element", exception);
return buildErrorResponse(exception, HttpStatus.NOT_FOUND, request);
}
@ExceptionHandler(MethodArgumentNotValidException.class)
@ResponseStatus(HttpStatus.UNPROCESSABLE_ENTITY)
public ResponseEntity<ErrorResponse> handleMethodArgumentNotValid(
MethodArgumentNotValidException ex,
WebRequest request
) {
ErrorResponse errorResponse = new ErrorResponse(
HttpStatus.UNPROCESSABLE_ENTITY.value(),
"Validation error. Check 'errors' field for details."
);
for (FieldError fieldError : ex.getBindingResult().getFieldErrors()) {
errorResponse.addValidationError(fieldError.getField(),
fieldError.getDefaultMessage());
}
return ResponseEntity.unprocessableEntity().body(errorResponse);
}
@ExceptionHandler(Exception.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public ResponseEntity<ErrorResponse> handleAllUncaughtException(
Exception exception,
WebRequest request){
log.error("Unknown error occurred", exception);
return buildErrorResponse(
exception,
"Unknown error occurred",
HttpStatus.INTERNAL_SERVER_ERROR,
request
);
}
private ResponseEntity<ErrorResponse> buildErrorResponse(
Exception exception,
HttpStatus httpStatus,
WebRequest request
) {
return buildErrorResponse(
exception,
exception.getMessage(),
httpStatus,
request);
}
private ResponseEntity<ErrorResponse> buildErrorResponse(
Exception exception,
String message,
HttpStatus httpStatus,
WebRequest request
) {
ErrorResponse errorResponse = new ErrorResponse(
httpStatus.value(),
exception.getMessage()
);
if(printStackTrace && isTraceOn(request)){
errorResponse.setStackTrace(ExceptionUtils.getStackTrace(exception));
}
return ResponseEntity.status(httpStatus).body(errorResponse);
}
private boolean isTraceOn(WebRequest request) {
String [] value = request.getParameterValues(TRACE);
return Objects.nonNull(value)
&& value.length > 0
&& value[0].contentEquals("true");
}
}