You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@cxf.apache.org by "Andy McCright (Jira)" <ji...@apache.org> on 2021/02/22 03:31:00 UTC

[jira] [Commented] (CXF-8427) Response exception mappers not invoked on MP async methods

    [ https://issues.apache.org/jira/browse/CXF-8427?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17288156#comment-17288156 ] 

Andy McCright commented on CXF-8427:
------------------------------------

Resolved with commit 01106a1171fd53c5077cbae74143e1421977d91e [1]

[1] https://github.com/apache/cxf/commit/a84f6e203940e93d81406031d571052ccb4e3fef

> Response exception mappers not invoked on MP async methods
> ----------------------------------------------------------
>
>                 Key: CXF-8427
>                 URL: https://issues.apache.org/jira/browse/CXF-8427
>             Project: CXF
>          Issue Type: Bug
>          Components: MicroProfile
>    Affects Versions: 3.4.2
>            Reporter: Andy McCright
>            Assignee: Andy McCright
>            Priority: Minor
>             Fix For: 3.5.0, 3.4.3
>
>
> MP Async methods have a return type of CompletionStage<?> and the exception processing should occur via the CS, not on the actual invocation of the method.  So if a response exception mapper is registered with a MP Rest Client interface, the associated exception should be on the throws clause for synchronous methods, but not necessarily for asynchronous methods.
> Here's and example:
> {code:java}
> public interface MyClient {
>   @GET 
>   @Path("sync")
>   String getSync() throws MyCustomException;
>   @GET 
>   @Path("async")
>   CompletionStage<String> getAync();
> {code}
> {code:java}
> public class MyCustomExceptionResponseMapper implements ResponseExceptionMapper<MyCustomException> {
>     @Override
>     public boolean handles(int status, MultivaluedMap<String, Object> headers) {
>         return status == 499;
>     }
>     @Override
>     public MyCustomException toThrowable(Response response) {
>         return new MyCustomException();
>     }
> }
> {code}
> For sync invocation, we would expect the invocation to throw the exception:
> {code:java}
> try {
>     myClient.getSync();
> } catch (MyCustomException ex) {
>     //...
> }
> {code}
> But for async invocation, we would expect the exception to be throw from the CompletionStage<?>, like:
> {code:java}
> CompletionStage<String> cs = myClient.getAsync();
> cs.exceptionally(ex -> {
>     Throwable cause = ex.getCause(); // ex should be a CompletionException
>     if (cause instanceof MyCustomException) {
>         // ...
>     }
> });
> // or
> try {
>     cs.toCompletableFuture().get();
> } catch (ExecutionException ex) {
>     Throwable cause = ex.getCause();
>     if (cause instanceof MyCustomException) {
>         //...
>     }
> }
> {code}
> Currently, the async flow fails because CXF is checking that the exception type is listed in the throws clause of the interface method signature.  So instead of throwing a MyCustomException wrapped in a CompletionException (or ExecutionException), it is throwing a wrapped WebApplicationException.



--
This message was sent by Atlassian Jira
(v8.3.4#803005)