Kotlinx.coroutines: withTimeout leaks exceptions caught inside it

Created on 14 Dec 2018  路  2Comments  路  Source: Kotlin/kotlinx.coroutines

This test fails:

  @Test
  fun `withTimeout leaks caught exceptions`() {
    val start = AtomicLong()
    try {
      runBlocking {
        start.set(System.nanoTime())
        withTimeout(100) {
          while (true) {
            try {
              GlobalScope.future {
                throw FooException()
              }.await()
            } catch (ignored: FooException) {
              println("caught FooException")
            }
          }
        }
      }
    } catch (e: CancellationException) {
      // OK
    } catch (e: FooException) {
      val elapsed = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - start.get())
      fail("expected CancellationException, got $e; elapsed time: ${elapsed}ms")
    }
  }

  class FooException : Exception("foo")

Output:

caught FooException (169 matches)
java.lang.AssertionError: expected CancellationException, got FooException: foo; elapsed time: 112ms

I would _never_ expect withTimeout to throw FooException, since it is caught inside it!

bug

Most helpful comment

Thanks. It has the same underlying problem as discussed in #830. I've confirmed it by applying Workaround#1 to the implementation of await() and it did fix the problem. Let's keep this bug open as a separate issue to make sure we don't forget to fix await().

All 2 comments

Note: GlobalScope.future is used only for presentation --- in reality, it is a j.u.concurrent.Future provided by a third-party library.

Thanks. It has the same underlying problem as discussed in #830. I've confirmed it by applying Workaround#1 to the implementation of await() and it did fix the problem. Let's keep this bug open as a separate issue to make sure we don't forget to fix await().

Was this page helpful?
0 / 5 - 0 ratings