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

@RolesAllowed causes Resource method returning CompletionStage to ignore exception mapping #21814

Closed
LoveFeelings opened this issue Nov 30, 2021 · 1 comment
Labels
kind/bug Something isn't working triage/duplicate This issue or pull request already exists

Comments

@LoveFeelings
Copy link

LoveFeelings commented Nov 30, 2021

Describe the bug

This issue is related to #20979. Looks to have been working in quarkus 2.3.2.Final, but the bug was interduced in quarkus 2.4.0.Final and is still present in quarkus 2.5.0.Final. Note that the code is fork'ed from @antoniomacri : antoniomacri/quarkus-completionstage-rolesallowed.

Consider the following method:

@RolesAllowed("protected-role")
@Path("/")
public class SampleResource {
    @POST
    @Path("protected")
    @Consumes(MediaType.APPLICATION_JSON)
    public CompletionStage<Response> getProtected(final Content data) throws Exception {
        return CompletableFuture.completedFuture(Response.ok().build());
    }
}

And consider that Content object's field name must not be null:

@Getter
@Setter
public class Content {
    @NotNull
    private String name;

}

When getProtected is called where Content object's field name is null, an unhandledAsynchronousException is thrown.
It is expected that exceptions are thrown in completionStages (in this case the @Valid throws the exception) and that these exceptions are correctly mapped. This do not look to be the case with RolesAllowedInterceptor.java:29 which calls the SecurityHandler.handle method(see below). It looks like the exception mapped is ignored on line 39:

public Object handle(InvocationContext ic) throws Exception {
if (alreadyHandled(ic)) {
return ic.proceed();
}
Class<?> returnType = ic.getMethod().getReturnType();
if (Uni.class.isAssignableFrom(returnType)) {
return constrainer.nonBlockingCheck(ic.getMethod(), ic.getParameters())
.onItem().transformToUni(new UniContinuation(ic));
} else if (CompletionStage.class.isAssignableFrom(returnType)) {
return constrainer.nonBlockingCheck(ic.getMethod(), ic.getParameters())
.onItem().transformToUni((s) -> {
try {
return Uni.createFrom().completionStage((CompletionStage<?>) ic.proceed());
} catch (Exception e) {
return Uni.createFrom().failure(e);
}
}).subscribeAsCompletionStage();
} else if (Multi.class.isAssignableFrom(returnType)) {
return constrainer.nonBlockingCheck(ic.getMethod(), ic.getParameters())
.onItem().transformToMulti(new MultiContinuation(ic));
} else {
constrainer.check(ic.getMethod(), ic.getParameters());
return ic.proceed();
}
}

Expected behavior

As the request contains incomplete content, it is expected to receive a CompletionStage with a response with 400 Bad Request. And that the exception mapping is not ignored.

Actual behavior

An unhandledAsynchronousException from resteasy with the return code 500 is returned.

In a QuarkusTest shows this error:
AM org.jboss.resteasy.core.SynchronousDispatcher unhandledAsynchronousException
ERROR: RESTEASY002020: Unhandled asynchronous exception, sending back 500

How to Reproduce?

Find code to reproduce here

Output of uname -a or ver

No response

Output of java -version

java 11

GraalVM version (if different from Java)

No response

Quarkus version or git rev

2.5.0.Final

Build tool (ie. output of mvnw --version or gradlew --version)

Maven 3.8.1

Additional information

No response

@LoveFeelings LoveFeelings added the kind/bug Something isn't working label Nov 30, 2021
@geoand
Copy link
Contributor

geoand commented Nov 30, 2021

This is a duplicate of #21679 and has already been fixed in main (the fix will be available in 2.5.1.Final)

@geoand geoand closed this as completed Nov 30, 2021
@geoand geoand added the triage/duplicate This issue or pull request already exists label Nov 30, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind/bug Something isn't working triage/duplicate This issue or pull request already exists
Projects
None yet
Development

No branches or pull requests

2 participants