Skip to content

Commit db5335a

Browse files
committed
Recover stacktrace on state-machine decision in AbstractContinuation
1 parent 675c30c commit db5335a

File tree

5 files changed

+8
-8
lines changed

5 files changed

+8
-8
lines changed

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

+2-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
package kotlinx.coroutines
66

77
import kotlinx.atomicfu.*
8+
import kotlinx.coroutines.internal.*
89
import kotlin.coroutines.*
910
import kotlin.coroutines.intrinsics.*
1011
import kotlin.jvm.*
@@ -133,7 +134,7 @@ internal abstract class AbstractContinuation<in T>(
133134
if (trySuspend()) return COROUTINE_SUSPENDED
134135
// otherwise, onCompletionInternal was already invoked & invoked tryResume, and the result is in the state
135136
val state = this.state
136-
if (state is CompletedExceptionally) throw state.cause
137+
if (state is CompletedExceptionally) throw recoverStackTrace(state.cause, this)
137138
return getSuccessfulResult(state)
138139
}
139140

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -280,4 +280,4 @@ internal fun <T> DispatchedTask<T>.resume(delegate: Continuation<T>, useMode: In
280280

281281

282282
@Suppress("NOTHING_TO_INLINE")
283-
private inline fun Continuation<*>.resumeWithStackTrace(exception: Throwable) = resumeWith(Result.failure(recoverStackTrace(exception, this)))
283+
internal inline fun Continuation<*>.resumeWithStackTrace(exception: Throwable) = resumeWith(Result.failure(recoverStackTrace(exception, this)))

core/kotlinx-coroutines-core/test/exceptions/StackTraceRecoveryInHierarchiesTest.kt

+2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
* Copyright 2016-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
33
*/
44

5+
@file:Suppress("DeferredResultUnused")
6+
57
package kotlinx.coroutines.exceptions
68

79
import kotlinx.coroutines.*

core/kotlinx-coroutines-core/test/exceptions/StackTraceRecoveryTest.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ class StackTraceRecoveryTest : TestBase() {
204204

205205
val causes = stacktrace.count("Caused by")
206206
assertNotEquals(0, causes)
207-
assertEquals(causes, traces.map { it.count("Caused by") }.sum())
207+
assertEquals(traces.map { it.count("Caused by") }.sum(), causes)
208208
}
209209

210210
private fun toStackTrace(t: Throwable): String {

integration/kotlinx-coroutines-jdk8/test/future/FutureTest.kt

+2-5
Original file line numberDiff line numberDiff line change
@@ -303,17 +303,14 @@ class FutureTest : TestBase() {
303303

304304
assertFalse(deferred.isCompleted)
305305
lock.unlock()
306-
307306
try {
308307
deferred.await()
309308
fail("deferred.await() should throw an exception")
310-
} catch (e: Exception) {
309+
} catch (e: CompletionException) {
311310
assertTrue(deferred.isCancelled)
312-
assertTrue(e is CompletionException) // that's how supplyAsync wraps it
313-
val cause = e.cause!!
311+
val cause = e.cause?.cause!! // Stacktrace augmentation
314312
assertTrue(cause is TestException)
315313
assertEquals("something went wrong", cause.message)
316-
assertSame(e, deferred.getCompletionExceptionOrNull()) // same exception is returns as thrown
317314
}
318315
}
319316

0 commit comments

Comments
 (0)