I need to add @ControllerAdvice
class to handle exceptions and return body with a message from the exception.
But when checking via postman, I keep getting the default body with 500Internal Server Error even though the breakpoint inside my ControllerAdvice class method fires.
console log:
WARN 24909 --- [nio-8081-exec-1] .m.m.a.ExceptionHandlerExceptionResolver : Failure in @ExceptionHandler com.javalibrary.controller.ControllerAdvice#handleApplicationException(RuntimeException)
org.springframework.web.HttpMediaTypeNotAcceptableException: Could not find acceptable representation
at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:315) ~[spring-webmvc-5.3.18.jar:5.3.18]
at org.springframework.web.servlet.mvc.method.annotation.HttpEntityMethodProcessor.handleReturnValue(HttpEntityMethodProcessor.java:219) ~[spring-webmvc-5.3.18.jar:5.3.18]
Response body:
{
"timestamp": "2022-04-18T19:13:14.183+00:00",
"status": 500,
"error": "Internal Server Error",
"path": "/api/v1/book/1"
}
My ControllerAdvice
class:
@org.springframework.web.bind.annotation.ControllerAdvice
public class ControllerAdvice {
@ExceptionHandler(RuntimeException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ResponseBody
ResponseEntity<ErrorResponse> handleApplicationException(RuntimeException e) {
return ResponseEntity.badRequest().body(new ErrorResponse(e.getMessage()));
}
}
build.gradle
plugins:
plugins {
id 'org.springframework.boot' version '2.6.6'
id 'io.spring.dependency-management' version '1.0.11.RELEASE'
id 'java'
}
build.gradle
dependencies:
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-actuator'
implementation 'org.springframework.boot:spring-boot-starter-data-mongodb'
implementation 'com.github.cloudyrock.mongock:mongock-spring-v5:4.1.14'
implementation 'com.github.cloudyrock.mongock:mongodb-springdata-v3-driver:4.1.14'
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
The reason for the error was that I have no public getters for ErrorResponse
.
So my class looked like this.
@AllArgsConstructor
class ErrorResponse {
private final String message;
}
Correct example 1:
class ErrorResponse {
private final String message;
public ErrorResponse(String message) {
this.message = message;
}
public String getMessage() {
return message;
}
}
Correct example 2 (with Lombok):
@Data
class ErrorResponse {
private final String message;
}
Correct example 3 (with record
):
record ErrorResponse(String message) { }