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'
}
CodePudding user response:
Spring is just telling you that it doesn't know how to properly serialize the response. The fact that you're getting this exception on the response side of things tells me that you're asking for a representation that you haven't registered a negotiator for.
When you make the request, make sure that you send an Accept
header of either application/json
, if you're using json, or */*
and let Spring just decide (in which case you'll probably get json unless you've overridden this). You also can send the request without the Accept
header at all.
CodePudding user response:
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) { }