Skip to content

Commit d562f26

Browse files
authored
Simplify internal handling of suppressed exceptions (#4007)
1 parent 53e93e8 commit d562f26

File tree

16 files changed

+29
-102
lines changed

16 files changed

+29
-102
lines changed

kotlinx-coroutines-core/common/src/CoroutineExceptionHandler.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ public fun handleCoroutineException(context: CoroutineContext, exception: Throwa
3535
internal fun handlerException(originalException: Throwable, thrownException: Throwable): Throwable {
3636
if (originalException === thrownException) return originalException
3737
return RuntimeException("Exception while trying to handle coroutine exception", thrownException).apply {
38-
addSuppressedThrowable(originalException)
38+
addSuppressed(originalException)
3939
}
4040
}
4141

kotlinx-coroutines-core/common/src/Exceptions.common.kt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,5 @@ internal expect class JobCancellationException(
2626

2727
internal class CoroutinesInternalError(message: String, cause: Throwable) : Error(message, cause)
2828

29-
internal expect fun Throwable.addSuppressedThrowable(other: Throwable)
3029
// For use in tests
3130
internal expect val RECOVER_STACK_TRACES: Boolean

kotlinx-coroutines-core/common/src/JobSupport.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,7 @@ public open class JobSupport constructor(active: Boolean) : Job, ChildJob, Paren
281281
val unwrapped = unwrap(exception)
282282
if (unwrapped !== rootCause && unwrapped !== unwrappedCause &&
283283
unwrapped !is CancellationException && seenExceptions.add(unwrapped)) {
284-
rootCause.addSuppressedThrowable(unwrapped)
284+
rootCause.addSuppressed(unwrapped)
285285
}
286286
}
287287
}
@@ -369,7 +369,7 @@ public open class JobSupport constructor(active: Boolean) : Job, ChildJob, Paren
369369
try {
370370
node.invoke(cause)
371371
} catch (ex: Throwable) {
372-
exception?.apply { addSuppressedThrowable(ex) } ?: run {
372+
exception?.apply { addSuppressed(ex) } ?: run {
373373
exception = CompletionHandlerException("Exception in completion handler $node for $this", ex)
374374
}
375375
}

kotlinx-coroutines-core/common/src/channels/Deprecated.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ internal fun consumesAll(vararg channels: ReceiveChannel<*>): CompletionHandler
5656
if (exception == null) {
5757
exception = e
5858
} else {
59-
exception.addSuppressedThrowable(e)
59+
exception.addSuppressed(e)
6060
}
6161
}
6262
exception?.let { throw it }

kotlinx-coroutines-core/common/src/flow/operators/Emitters.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ private suspend fun <T> FlowCollector<T>.invokeSafely(
215215
try {
216216
action(cause)
217217
} catch (e: Throwable) {
218-
if (cause !== null && cause !== e) e.addSuppressedThrowable(cause)
218+
if (cause !== null && cause !== e) e.addSuppressed(cause)
219219
throw e
220220
}
221221
}

kotlinx-coroutines-core/common/src/internal/DispatchedTask.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ internal abstract class DispatchedTask<in T> internal constructor(
139139
internal fun handleFatalException(exception: Throwable?, finallyException: Throwable?) {
140140
if (exception === null && finallyException === null) return
141141
if (exception !== null && finallyException !== null) {
142-
exception.addSuppressedThrowable(finallyException)
142+
exception.addSuppressed(finallyException)
143143
}
144144

145145
val cause = exception ?: finallyException

kotlinx-coroutines-core/common/src/internal/OnUndeliveredElement.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ internal fun <E> OnUndeliveredElement<E>.callUndeliveredElementCatchingException
1919
// undeliveredElementException.cause !== ex is an optimization in case the same exception is thrown
2020
// over and over again by on OnUndeliveredElement
2121
if (undeliveredElementException != null && undeliveredElementException.cause !== ex) {
22-
undeliveredElementException.addSuppressedThrowable(ex)
22+
undeliveredElementException.addSuppressed(ex)
2323
} else {
2424
return UndeliveredElementException("Exception in undelivered element handler for $element", ex)
2525
}

kotlinx-coroutines-core/concurrent/test/ConcurrentExceptionsStressTest.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ class ConcurrentExceptionsStressTest : TestBase() {
4848
val completionException = deferred.getCompletionExceptionOrNull()
4949
val cause = completionException as? StressException
5050
?: unexpectedException("completion", completionException)
51-
val suppressed = cause.suppressed
51+
val suppressed = cause.suppressedExceptions
5252
val indices = listOf(cause.index) + suppressed.mapIndexed { index, e ->
5353
(e as? StressException)?.index ?: unexpectedException("suppressed $index", e)
5454
}
@@ -62,6 +62,6 @@ class ConcurrentExceptionsStressTest : TestBase() {
6262
throw IllegalStateException("Unexpected $msg exception", e)
6363
}
6464

65-
private class StressException(val index: Int) : SuppressSupportingThrowable()
65+
private class StressException(val index: Int) : Throwable()
6666
}
6767

kotlinx-coroutines-core/concurrent/test/ConcurrentTestUtilities.common.kt

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,26 @@
55
package kotlinx.coroutines.exceptions
66

77
import kotlinx.coroutines.*
8+
import kotlin.concurrent.Volatile
9+
import kotlin.random.*
810

9-
internal expect open class SuppressSupportingThrowable() : Throwable
10-
expect val Throwable.suppressed: Array<Throwable>
11-
// Unused on purpose, used manually during debugging sessions
12-
expect fun Throwable.printStackTrace()
11+
fun randomWait() {
12+
val n = Random.nextInt(1000)
13+
if (n < 500) return // no wait 50% of time
14+
repeat(n) {
15+
BlackHole.sink *= 3
16+
}
17+
// use the BlackHole value somehow, so even if the compiler gets smarter, it won't remove the object
18+
val sinkValue = if (BlackHole.sink > 16) 1 else 0
19+
if (n + sinkValue > 900) yieldThread()
20+
}
21+
22+
private object BlackHole {
23+
@Volatile
24+
var sink = 1
25+
}
1326

14-
expect fun randomWait()
27+
expect inline fun yieldThread()
1528

1629
expect fun currentThreadName(): String
1730

kotlinx-coroutines-core/jsAndWasmShared/src/Exceptions.kt

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,5 @@ internal actual class JobCancellationException public actual constructor(
3535
(message!!.hashCode() * 31 + job.hashCode()) * 31 + (cause?.hashCode() ?: 0)
3636
}
3737

38-
@Suppress("NOTHING_TO_INLINE")
39-
internal actual inline fun Throwable.addSuppressedThrowable(other: Throwable) { /* empty */ }
40-
4138
// For use in tests
4239
internal actual val RECOVER_STACK_TRACES: Boolean = false

0 commit comments

Comments
 (0)