Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Preventing RxJava from wrapping my custom exception into composite one

I was given a task to make implementation using RxJava, and safeguard in such way, that if any error happens, it gets wrapped into custom exception.

Problem is, that regardless of what I do RxJavaPlugin decides to wrap my exception into CompositeException even when there is only one. Which fails tests.

I've tried everything I could find on the google all the way up to actually overwriting RxJavaPlugin's global error handler, but it ignores attempted changes.

implementation of function that is supposed to throw it at the moment of writing this post

Single<BigDecimal> summarizeConfirmedTransactions() throws SummarizationException {
        try{
            Observable<Transaction> observableTransactions = transactions.get()
                    .doOnError(throwable -> {
                        Exceptions.propagate(throwable);
                    });
            Observable<Confirmation> observableConfirmations = confirmations.get()
                    .doOnError(throwable -> {
                        Exceptions.propagate(throwable);
                    });
            return Observable.zip(observableTransactions, observableConfirmations, (t, c) -> new ConfirmableTransaction(t.transactionId, c.isConfirmed, t.value))
                    .filter(confirmableTransaction -> confirmableTransaction.isConfirmed)
                    .map(t -> t.value)
                    .reduce(BigDecimal::add)
                    .toSingle()
                    .doOnError(throwable -> {
                        Exceptions.propagate(throwable);
                    });
        }catch(Exception e)
        {
            throw new SummarizationException(e.getMessage());
        }

Assertion in test fails because exception ultimately thrown is CompositeException with single exception inside of it. and I am required to have it be of SummarizationException.class

big thanks in advance.

Edit: On request, here is code used to test the solution. I am not allowed to modify this one.

    @Test
    public void shouldWrapErrorIntoException() {
        final ConfirmedTransactionSummarizer summarizer =
                new ConfirmedTransactionSummarizer(ALL_CONFIRMED::transactions, () -> Observable.error(new RuntimeException("Booom")));


        summarizer
                .summarizeConfirmedTransactions()
                .subscribe(testObserver);

        testObserver.assertError(SummarizationException.class);
        testObserver.assertErrorMessage("Booom");
    }

PS. I've asked the giver of the task, he said that "I'm the only one with such problem" and that I should not overcomplicate things and go for easiest solution.... which results in composite exception of 3 exceptions - one of which is my exception wrap and other two are instances of RuntimeException inserted by test code.

like image 834
Cemenotar Avatar asked Oct 23 '25 12:10

Cemenotar


1 Answers

Ok, so after a little bit of more digging, and with helpful tip from a friend I've managed to nail down intention of the task:

What I was supposed to do there was:

Single<BigDecimal> summarizeConfirmedTransactions() throws SummarizationException {
  Observable<Transaction> observableTransactions = transactions.get();
  Observable<Confirmation> observableConfirmations = confirmations.get();

  return Observable.zip(observableTransactions, observableConfirmations,
    (t, c) -> new ConfirmableTransaction(c.isConfirmed, t.value))
      .filter(confirmableTransaction -> confirmableTransaction.isConfirmed)
      .map(t -> t.value)
      .reduce(BigDecimal::add)
      .toSingle()
      .onErrorResumeNext(th -> Single.error(new SummarizationException(th.getMessage())));
}

TL:DR I was not supposed to "wrap" errors into thrown exception but wrap them into error response containing exception.

like image 57
Cemenotar Avatar answered Oct 26 '25 01:10

Cemenotar



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!