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

Andriy Redko commented on CXF-8349:
-----------------------------------

Hey [~kjq]

Sounds good, thank you. I was researching the ways to properly handle such 
cases, specifically in context of Spring Reactor ecosystem, [1], [2], [3] and I 
think there is an acceptable approach to manage that (mixed response to be 
precise). It does violate some of your assumptions and I am curious to hear 
your opinion.

 # If publisher has emitted at least one element, it/they cannot be discarded 
and must be delivered to the subscriber. What it means practically in the 
context of this issue is that the *expectation is to get the error response 
only* won't hold because in general case, result is streamed and elements are 
written to the response stream one by one. In this case the only option the 
CXF/server has *is to try to propagate response status* (as it does now) but 
not the exception payload (as it also does now) since it will lead to 
mixed/misformatted response (this issue). The simplest example to illustrate 
that is using *concatMap / delayElement*, elements are sent over the wire way 
before the exception occurs.

{noformat}
    @GET
    @Path("/test3")
    @Produces(APPLICATION_JSON)
    @Consumes(APPLICATION_JSON)
    public Flux<String> getError()
    {
        return Flux
            .range(1, 5)
            .concatMap(item ->
                     {
                         if (item <= 4)
                         {
                             return Mono
                                  .just("item: " + item)
                                  .delayElement(Duration.ofSeconds(3)); ;
                         }
                         else
                         {
                             System.out.println("---Hitting exception");
                             return error(new NotFoundException());
                         }
                     })
            .onErrorMap(e -> new RuntimeException(e));
    }{noformat}

 # If publisher emitted no elements but the error first, the *expectation to 
get the error response only* would hold true. 

This behavior is in tact with vanilla Spring WebFlux (depending on the 
container being used, it is not always possible to set the response code, 
easily observed with reactor-netty fe), at least this is what I have observed 
and understood from reading the code.

What do you think, does it make sense to you?
Thanks.


[1] https://github.com/spring-projects/spring-framework/issues/20600
[2] 
https://github.com/reactor/reactor-netty/commit/396895d480e95fe16b01cefa3d8260bf0528477f
[3] 
https://github.com/spring-projects/spring-framework/commit/f05175586e32e660ff190311f0b102c2b3b3a398

> Flux Returns Mixed Response on Errors and Mono Hangs when Empty
> ---------------------------------------------------------------
>
>                 Key: CXF-8349
>                 URL: https://issues.apache.org/jira/browse/CXF-8349
>             Project: CXF
>          Issue Type: Bug
>          Components: JAX-RS
>    Affects Versions: 3.4.0
>         Environment: *Versions:*
>  * Spring Boot 2.3.4.RELEASE
>  * Apache CXF 3.4.0 (using the new BOM + reactor extension)
>  * Undertow (latest from spring boot bom)
>  * Jackson (latest from spring boot bom)
>  * JDK 11
> We use CXF instead of Spring for all Mono/Flux REST endpoints.  Outside of 
> the error handling, everything works great.
>            Reporter: KimJohn Quinn
>            Priority: Critical
>
> It looks like we have similar/continuing issues as originally outlined in 
> CXF-8022.
> *Two issues I have are:*
>  * Flux "error" returns a mixed response
>  * Mono that returns empty seems to hang on thread and never return.
> {color:#de350b}These are super important for us because it makes handling 
> exceptions somewhat difficult (if there is a workaround that would be 
> acceptable too as this is only with errors) and empty mono results, which can 
> happen, unhandleable. We have a lot invested in using CXF as we start to move 
> to Kamel and eventually Quarkus later and would not want to use Spring 
> controllers.{color}
> ----
> +{color:#0747a6}*Problem 1: Flux error returns mixed response*{color}+
> Using this test, when an exception is thrown from within a step in the stream 
> the expectation is to get the error response only (handled by an 
> ExceptionMapper).  Most cases this is true.
> This appears to happen only with a Flux and if the error is thrown before the 
> last step in the chain (i.e. call a --> call b --> call c).  If there are 
> multiple steps it _appears_ the last one will return an error correctly, in 
> the example call a and call b would return the mixed response where as call c 
> returns the error correctly.
> *Using this code (replica code in the original issue CXF-8022):*
> {code:java}
> @GET
>     @Path("/test3")
>     @Produces(APPLICATION_JSON)
>     @Consumes(APPLICATION_JSON)
>     public Flux<String> getError()
>     {
>         return Flux
>             .range(1, 5)
>             .flatMap(item ->
>                      {
>                          if (item <= 4)
>                          {
>                              return Mono.just("item: " + item);
>                          }
>                          else
>                          {
>                              System.out.println("---Hitting exception");
>                              return error(new NotFoundException());
>                          }
>                      })
>             .onErrorMap(e -> new RuntimeException(e));
>     }
> {code}
>  *Returns this result (error):*
> {code:java}
>  [item: 1,item: 2,item: 3,item: 4
> ]{
>     "status": 404,
>     "phrase": "Not Found",
>     "message": "javax.ws.rs.NotFoundException: HTTP 404 Not Found",
>     "path": "/projects/xxx/test3",
>     "timestamp": 1601172421939,
>     "trace": [
>         "at 
> aaa.bbb.project.services.ProjectResource.lambda$getError$0(ProjectResource.java:133)"
>     ]
> }{code}
> ----
> +{color:#0747a6}*Problem 2: Mono hangs returning empty*{color}+
> Also, as a side node, I seem to have a similar problem with an empty Mono 
> (whereas the ticket above the problem was in the Flux)
> {code:java}
>     @GET
>     @Path("/test1a")
>     @Produces(APPLICATION_JSON)
>     @Consumes(APPLICATION_JSON)
>     public Mono<Map> getMono()
>     {
>         return Mono.empty();
>     }
> {code}
> This will hang and not return a result.  Pausing it while debugging shows it 
> holding up on a Thread parking...
>  



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

Reply via email to