Skip to content

Commit

Permalink
Fix Promise.await() never resuming if the promise rejected with a non…
Browse files Browse the repository at this point in the history
…-Throwable (#4120)
  • Loading branch information
shepeliev authored Dec 9, 2024
1 parent 0e1c157 commit 6b73546
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 1 deletion.
2 changes: 1 addition & 1 deletion kotlinx-coroutines-core/js/src/Promise.kt
Original file line number Diff line number Diff line change
Expand Up @@ -63,5 +63,5 @@ public fun <T> Promise<T>.asDeferred(): Deferred<T> {
public suspend fun <T> Promise<T>.await(): T = suspendCancellableCoroutine { cont: CancellableContinuation<T> ->
this@await.then(
onFulfilled = { cont.resume(it) },
onRejected = { cont.resumeWithException(it) })
onRejected = { cont.resumeWithException(it as? Throwable ?: Exception("Non-Kotlin exception $it")) })
}
23 changes: 23 additions & 0 deletions kotlinx-coroutines-core/js/test/PromiseTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -83,4 +83,27 @@ class PromiseTest : TestBase() {
if (seq != 1) error("Unexpected result: $seq")
}
}

@Test
fun testAwaitPromiseRejectedWithNonKotlinException() = GlobalScope.promise {
lateinit var r: (dynamic) -> Unit
val toAwait = Promise<dynamic> { _, reject -> r = reject }
val throwable = async(start = CoroutineStart.UNDISPATCHED) {
assertFails { toAwait.await() }
}
r("Rejected")
assertContains(throwable.await().message ?: "", "Rejected")
}

@Test
fun testAwaitPromiseRejectedWithKotlinException() = GlobalScope.promise {
lateinit var r: (dynamic) -> Unit
val toAwait = Promise<dynamic> { _, reject -> r = reject }
val throwable = async(start = CoroutineStart.UNDISPATCHED) {
assertFails { toAwait.await() }
}
r(RuntimeException("Rejected"))
assertIs<RuntimeException>(throwable.await())
assertEquals("Rejected", throwable.await().message)
}
}
23 changes: 23 additions & 0 deletions kotlinx-coroutines-core/wasmJs/test/PromiseTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -84,4 +84,27 @@ class PromiseTest : TestBase() {
null
}
}

@Test
fun testAwaitPromiseRejectedWithNonKotlinException() = GlobalScope.promise {
lateinit var r: (JsAny) -> Unit
val toAwait = Promise<JsAny?> { _, reject -> r = reject }
val throwable = async(start = CoroutineStart.UNDISPATCHED) {
assertFails { toAwait.await<JsAny?>() }
}
r("Rejected".toJsString())
assertIs<JsException>(throwable.await())
}

@Test
fun testAwaitPromiseRejectedWithKotlinException() = GlobalScope.promise {
lateinit var r: (JsAny) -> Unit
val toAwait = Promise<JsAny?> { _, reject -> r = reject }
val throwable = async(start = CoroutineStart.UNDISPATCHED) {
assertFails { toAwait.await<JsAny?>() }
}
r(RuntimeException("Rejected").toJsReference())
assertIs<RuntimeException>(throwable.await())
assertEquals("Rejected", throwable.await().message)
}
}

0 comments on commit 6b73546

Please sign in to comment.