Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Do not try to apply JsonView to failed responses #10022

Merged
merged 4 commits into from
Oct 26, 2023
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,10 @@ public final Publisher<? extends MutableHttpResponse<?>> doFilter(HttpRequest<?>
if (routeInfo != null) {
final Optional<Class<?>> viewClass = routeInfo.findAnnotation(JsonView.class)
.flatMap(AnnotationValue::classValue);
if (viewClass.isPresent()) {
if (viewClass.isPresent() &&
// if this is an error response, the response body does not come from the controller
!response.getAttributes().contains(HttpAttributes.EXCEPTION)) {
yawkat marked this conversation as resolved.
Show resolved Hide resolved

final Optional<?> optionalBody = response.getBody();
if (optionalBody.isPresent()) {
Object body = optionalBody.get();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,13 @@ package io.micronaut.http.server.netty.jackson

import com.fasterxml.jackson.annotation.JsonView
import io.micronaut.http.HttpResponse
import io.micronaut.http.HttpStatus
import io.micronaut.http.annotation.Body
import io.micronaut.http.annotation.Controller
import io.micronaut.http.annotation.Error
import io.micronaut.http.annotation.Get
import io.micronaut.http.annotation.Post
import io.micronaut.http.hateoas.JsonError
import reactor.core.publisher.Flux
import reactor.core.publisher.Mono

Expand Down Expand Up @@ -77,4 +80,24 @@ class JsonViewController {
assert model.password == null
return HttpResponse.ok(model)
}

@JsonView(Views.Public)
@Get("/failing")
TestModel failing() {
throw new Failure1()
}

@JsonView(Views.Public)
@Get("/failing-with-route")
TestModel failingWithRoute() {
throw new Failure2()
}

@Error
HttpResponse<JsonError> errorRoute(Failure2 f) {
return HttpResponse.status(HttpStatus.INTERNAL_SERVER_ERROR).body(new JsonError("failure2"));
}

static class Failure1 extends Exception {}
static class Failure2 extends Exception {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ import io.micronaut.core.type.Argument
import io.micronaut.http.HttpRequest
import io.micronaut.http.HttpResponse
import io.micronaut.http.client.HttpClient
import io.micronaut.http.client.exceptions.HttpClientResponseException
import io.micronaut.http.hateoas.JsonError
import io.micronaut.runtime.server.EmbeddedServer
import spock.lang.AutoCleanup
import spock.lang.Shared
Expand Down Expand Up @@ -126,4 +128,20 @@ class JsonViewServerFilterSpec extends Specification {
rsp.body().birthdate == null
rsp.body().password == null
}

def "errors are written properly"() {
when:
client.toBlocking().exchange(HttpRequest.GET('/jsonview/failing'), TestModel)

then:
def f = thrown HttpClientResponseException
f.response.getBody(JsonError).get().message == "Internal Server Error"

when:
client.toBlocking().exchange(HttpRequest.GET('/jsonview/failing-with-route'))

then:
HttpClientResponseException e = thrown()
e.response.getBody(JsonError).get().message == "failure2"
}
}
Loading