javaspring-bootrestcontroller-advice

HttpMediaTypeNotAcceptableException: Could not find acceptable representation for @ControllerAdvice


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'
}

Solution

  • 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) { }