-1

After upgrading the micronaut application from 2.5.12 to 3.0.0 and using the Project reactor as reactive stream. The Global exception handler method never get called.

 public class GlobalException extends RuntimeException{
        public GlobalException(Throwable throwable){super(throwable);}
    }

@Produces
@Singleton
@Requires(classes = {GlobalException.class, ExceptionHandler.class})
public class GlobalExceptionHandler implements ExceptionHandler<GlobalException, HttpResponse> {
    private static final Logger LOG = LoggerFactory.getLogger(GlobalExceptionHandler.class);

    @Override
    public HttpResponse handle(HttpRequest request, GlobalException exception) {
        LOG.error(exception.getLocalizedMessage());
        LOG.error(exception.getCause().getMessage());
        Arrays.stream(exception.getStackTrace()).forEach(item -> LOG.error(item.toString()));
        return HttpResponse.serverError(exception.getLocalizedMessage());
    }
}

On exception with below code, the handler method never get called

@Override
    public Flux<FindProductCommand> get(ProductSearchCriteriaCommand searchCriteria) {
        LOG.info("Controller --> Finding all the products");
        return iProductManager.find(searchCriteria).onErrorMap(throwable -> {
            return new GlobalException(throwable);
        });
    }

I had this code Global exception handling in micronaut Java from rxjava 3 which was working fine, however, now with project reactor it is not working

San Jaisy
  • 15,327
  • 34
  • 171
  • 290

3 Answers3

0

If you only intend to produce a single element it should be annotated with @SingleResult Or use Mono

@Override
@SingleResult
public Flux<List<FindProductCommand>> freeTextSearch(String text) {
    LOG.info("Controller --> Finding all the products");
    return iProductManager.findFreeText(text)
            .onErrorMap(throwable -> {
                throw new GlobalException(throwable);
            });
}
San Jaisy
  • 15,327
  • 34
  • 171
  • 290
0

Try this one:

@Override
    public Flux<FindProductCommand> get(ProductSearchCriteriaCommand searchCriteria) {
        LOG.info("Controller --> Finding all the products");
        return iProductManager
                  .find(searchCriteria)
                  .onErrorResume(e -> Mono.error(new GlobalException("My exception", e));
    }
skv
  • 1
  • 1
0

One reason for this might be that in your code, looking at this bit:

@Override
public Flux<FindProductCommand> get(ProductSearchCriteriaCommand searchCriteria) {
    LOG.info("Controller --> Finding all the products");
    return iProductManager.find(searchCriteria).onErrorMap(throwable -> {
        return new GlobalException(throwable);
    });
}

If the code iProductManager.find(searchCriteria) is calling a rest endpoint and getting a 404 not found, you will not get an error in the error handler. Rather the result is that you will get the equivalent of an Optional.empty().

If you want to force en error, you could change it to something like:

iProductManager.find(searchCriteria).switchIfEmpty(Mono.error(...))

pbthorste
  • 309
  • 2
  • 6