@@ -15,7 +15,7 @@ import kotlin.internal.*
15
15
/* *
16
16
* Creates cold [mono][Mono] that will run a given [block] in a coroutine and emits its result.
17
17
* Every time the returned mono is subscribed, it starts a new coroutine.
18
- * If [block] result is `null`, [MonoSink.success] is invoked without a value.
18
+ * If [block] completes with `null` or its execution was cancelled , [MonoSink.success] is invoked without a value.
19
19
* Unsubscribing cancels running coroutine.
20
20
*
21
21
* Coroutine context can be specified with [context] argument.
@@ -68,11 +68,13 @@ private class MonoCoroutine<in T>(
68
68
69
69
override fun onCancelled (cause : Throwable , handled : Boolean ) {
70
70
try {
71
- /*
72
- * sink.error handles exceptions on its own and, by default, handling of undeliverable exceptions is a no-op.
73
- * Guard potentially non-empty handlers against meaningless cancellation exceptions
74
- */
75
- if (getCancellationException() != = cause) {
71
+ if (getCancellationException() == = cause) {
72
+ /* * Cancellation exceptions are meaningless to the user, so we present them as absences of a value. If
73
+ * [sink] is already in a terminal state, this call will be ignored altogether, which is good. */
74
+ sink.success()
75
+ } else {
76
+ /* * If [sink] turns out to already be in a terminal state, this exception will be passed through the
77
+ * [Hooks.onErrorDropped] hook, which is the way to signal undeliverable exceptions in Reactor. */
76
78
sink.error(cause)
77
79
}
78
80
} catch (e: Throwable ) {
0 commit comments