NeverSleeps
NeverSleeps

Reputation: 1902

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

Upvotes: 4

Views: 5540

Answers (2)

NeverSleeps
NeverSleeps

Reputation: 1902

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

Upvotes: 9

lane.maxwell
lane.maxwell

Reputation: 5872

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.

Upvotes: 1

Related Questions