reactor / reactor-kotlin-extensions

Reactor Kotlin Support
Apache License 2.0
143 stars 21 forks source link

retry extension methods throw RetryExhaustedException while the core Mono.retry throws the original exception #37

Closed dmutterSF closed 2 years ago

dmutterSF commented 2 years ago

Summary

While exceptions rethrown by Mono.retry can get matched by onErrorResume, exceptions thrown by the extension methods like retryExponentialBackoff can not due as they throw a RetryExhaustedException.

Example code

    private fun doStuff(): Mono<Any> {
        return fetchStuff()
            .delayElement(ofSeconds(2)) // trigger timeout
            .timeout(ofSeconds(1))
            .retryExponentialBackoff(1, ofSeconds(1))
            .onErrorResume(TimeoutException::class) {
                println("foo")
                Mono.empty()
            }
            .onErrorResume {
                if (it.cause is TimeoutException) {
                    println("bar")
                    Mono.empty()
                } else {
                    println("unknown error $it")
                    Mono.error(it)
                }
            }
    }

Expected

Console output: foo

Actual

Console output: bar

Workaround

as shown in the example code manually matching the class works. so replacing

            .onErrorResume(TimeoutException::class) {
                println("foo")
                Mono.empty()
            }

with

            .onErrorResume {
                if (it.cause is TimeoutException) {
                    println("bar")
                    Mono.empty()
                } else {
                    println("unknown error $it")
                    Mono.error(it)
                }
            }

will work with both the core library Mono.retry and the extension methods.

Improvement

add @Throws annotation to the retry extensions methods and mention that they throw a RetryExhaustedException contain the original Exception as cause.

Environment

Reactor versions: 3.4.6 Reactor Kotlin Extension Version: 1.1.5 JVM Version: 11 Kotlin Version: 1.6.10

dmutterSF commented 2 years ago

I noticed that the exception thrown by the retry extension methods is RetryExhaustedException with the original exception as cause but that confused me as the Mono.retry reactor.core method just rethrows the same Exception