question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Quarkus Reactive Mutiny - Composite Exception encapsulation on Runtime Exceptions and @ExceptionHandler

See original GitHub issue

Description

I am evaluating quarkus 1.6 and reactive Mutiny for reactive routes. My experience with quarkus mutiny exception handling is not so great . The current problem I have is if I throw a RuntimeException down in the service layer or data layer . The exception gets encapsulated as a CompositeException with a list of causes where one of the causes is the the RuntimeException thrown. This means that I have to always Parse the CompositeException to retrieve the actual exception which I have thrown to determine the HTTP status response ( of whether to throw a 500 or 422 or something else) .

Code Snippet - Current :

return Uni.createFrom().item(getRequest).flatMap(request ->{
  log.info("Request Received successfully {}", kv("someRequest", request));
  return xyzService.get(request, transactionContext);
}).onItemOrFailure().apply((paList, throwable) ->{
  if (paList != null) {
    return Response.ok(somePOJO).build();
  }

  if (throwable != null) {
    if (throwable instanceof CompositeException) {
      CompositeException compositeException = (CompositeException) throwable;
      Optional < Throwable > exception = isExceptionInstanceOf(compositeException, XYZRuntimeException.class);
      if (exception.isPresent()) {
        return Response.serverError().status(500).entity(somePOJO).build();
      }
    }

    if (throwable instanceof CircuitBreakerOpenException) {
      return Response.serverError().status(500).entity(somePOJO).build();

    }
  }

  return Response.serverError().status(500).entity(somePOJO).build();

});

Code Snippet - Expected :


//Controller logic 
return Uni.createFrom().item(getRequest)
                .flatMap(request -> {
                    log.info("Request Received successfully {}", kv("someRequest", request));
                    return xyzService.get(request, transactionContext);
                })
                .onItem()
                .apply(paList -> {
                    if (paList != null) {
                        return Response.ok(somePOJO)
                                .build();
                    }

                   return Response.serverError()
                            .status(500)
                            .entity(somePOJO)
                            .build();

                });

//Exception Handler can be in the same class or a different class ( different class will be annotated as @ControllerAdvice)
@ExceptionHandler
public Uni<Response> handleXYZException(XYZRuntimeException exception, <<FrameworkContextObject>> obj){
   
                                return Response.serverError()
                                        .status(500)
                                        .entity(somePOJO)
                            .build();
     
}

Implementation ideas

Can we have something similar to spring webflux , where if a RuntimeException is thrown from the data layer

a) Exactly same exception is captured in the error block of the controller class without needing to parse an encapsulated exception .

b) The Spring Boot framework has a @ControllerAdvice and @ExceptionHandler annotations to cleanly segregating the class for handling exceptions and controller. Can the same be available for Quarkus Reactive Mutiny extension.

c) The Spring boot framework has ServerWebExchange object which we can use as a context object to pass custom context . The good thing of this serverwebExchange object is that it is injected automatically as part of @ExceptionHandler Method making it easy to pass Context objects to exception handling methods . Can we have something similar in quarkus / reactive mutiny ?

(If you have any implementation ideas, they can go here, however please note that all design change proposals should be posted to the Quarkus developer mailing list (or the corresponding Google Group; see the decisions process document for more information).

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:22 (11 by maintainers)

github_iconTop GitHub Comments

1reaction
harry9111985commented, Aug 26, 2020

Thanks @cescoffier . that works .

@mkouba : Is there a plan on adding this feature for exception type based method resolvers in the next 1,2 or 3 month roadmap for vertx-io web ?

@Route(path = "/*", type = FAILURE , exception = {XYZRuntimeException.class,IIegalArgumentException.class})
public void handleExceptionTypeX(RoutingContext context) {}
@Route(path = "/*", type = FAILURE , exception = {DEFRuntimeException.class})
public void handleExceptionTypeY(RoutingContext context) {}
1reaction
cescoffiercommented, Aug 25, 2020

if i am throwing one xyz runtime exception from down my chain why should it be wrapped as a CompositeException… can it not be simply thrown up the reactive chain as xyz runtimeException. ?

CompositeExceptions are only created if your first failure (the RuntimeException) triggers a second failure. So, you have at least 2 failures.

Another situation where CompositeException is used is when you combine multiple actions and explicitly require to collect all the failures. In this case, if there is more than one a CompositeException is used. Again, you have multiple failures.

Note that you should be able to retrieve the initial “main” failure using getCause().

Read more comments on GitHub >

github_iconTop Results From Across the Web

How to handle failures with Mutiny - Quarkus
Failures are events. First, Mutiny is an event-driven reactive programming library. With Mutiny, you handle events.
Read more >
Peeking at the streams - Quarkus
Mutiny is an event-driven Reactive Programming library. Like other reactive programming libraries, it uses streams as the primary construct.
Read more >
Using the REST Client Reactive - Quarkus
This guide explains how to use the REST Client Reactive in order to interact with REST APIs. REST Client Reactive is the REST...
Read more >
Writing REST Services with RESTEasy Reactive - Quarkus
When an exception occurs in RESTEasy Reactive request parameter handling code, the exception is not printed by default to the log (for ...
Read more >
Mutiny and the Reactiverse - Quarkus
Following the reactive nature of Vert.x, the API contains mostly asynchronous methods. These methods are following a syntax convention: public ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found