3.x: Change how the cause of CompositeException is generated by akarnokd · Pull Request #6748 · ReactiveX/RxJava (original) (raw)

This PR changes how CompositeException.getCause creates a cause exception on demand. In 1.x and 2.x, the code tried to link up the various inner exceptions via their initCause, which was in on itself fishy as well as could lead to excessive memory usage.

Instead, the new code will present the inner exceptions as part of a formatted message, which in theory, should be still picked up by IDE exception listings and allow navigation:

Multiple exceptions (2)
|-- io.reactivex.rxjava3.exceptions.TestException: ex3
    at io.reactivex.rxjava3.exceptions.CompositeExceptionTest.nestedMultilineMessage(CompositeExceptionTest.java:341)
|-- io.reactivex.rxjava3.exceptions.TestException: ex4
    at io.reactivex.rxjava3.exceptions.CompositeExceptionTest.nestedMultilineMessage(CompositeExceptionTest.java:342)
  |-- io.reactivex.rxjava3.exceptions.CompositeException: 2 exceptions occurred. 
      at io.reactivex.rxjava3.exceptions.CompositeExceptionTest.nestedMultilineMessage(CompositeExceptionTest.java:337)
    |-- io.reactivex.rxjava3.exceptions.CompositeException.ExceptionOverview: 
        Multiple exceptions (2)
        |-- io.reactivex.rxjava3.exceptions.TestException: ex1
            at io.reactivex.rxjava3.exceptions.CompositeExceptionTest.nestedMultilineMessage(CompositeExceptionTest.java:335)
        |-- io.reactivex.rxjava3.exceptions.TestException: ex2
            at io.reactivex.rxjava3.exceptions.CompositeExceptionTest.nestedMultilineMessage(CompositeExceptionTest.java:336)

image

There are a few formatting conveniences:

Multiple exceptions (2)
|-- io.reactivex.rxjava3.exceptions.TestException: ex1
    at io.reactivex.rxjava3.exceptions.CompositeExceptionTest.reoccurringException(CompositeExceptionTest.java:316)
  |-- io.reactivex.rxjava3.exceptions.TestException: ex0
      at io.reactivex.rxjava3.exceptions.CompositeExceptionTest.reoccurringException(CompositeExceptionTest.java:315)
|-- io.reactivex.rxjava3.exceptions.TestException: ex2
    at io.reactivex.rxjava3.exceptions.CompositeExceptionTest.reoccurringException(CompositeExceptionTest.java:319)
  |-- io.reactivex.rxjava3.exceptions.TestException: ex1
      at io.reactivex.rxjava3.exceptions.CompositeExceptionTest.reoccurringException(CompositeExceptionTest.java:316)
      |-- (cause not expanded again) io.reactivex.rxjava3.exceptions.TestException: ex0

Currently, only the first line of the stacktraces are shown because it can get quite long (and thus memory consuming) to list them all. Maybe a system parameter can be introduced to control the verbosity.

Fixes #6747