-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Description
Describe the bug
When throwing an exception in a coroutine scope it sometimes becomes nested one level too deep in the enclosing exception.
For example, if I throw a: TestException(IllegalStateException("test"))
(a TestException with a cause of IllegalStateException with a message), then the coroutine scope will throw an exception that is: TestException(TestException(IllegalStateException("test")))
.
Provide a Reproducer
The following test will fail as a result of this bug:
@Test
fun testNestedException() = runTest {
val result = runCatching {
coroutineScope<Unit> {
throw NestedException(IllegalStateException("ERROR"))
}
}
val ex = result.exceptionOrNull() ?: error("Expected to fail")
assertTrue(ex is NestedException)
assertTrue(ex.cause is IllegalStateException)
assertEquals("ERROR", (ex.cause as IllegalStateException).message)
}
class NestedException : RuntimeException {
constructor(message: String) : super(message)
constructor(cause: Throwable) : super(cause)
constructor() : super()
}
I can get this test to not fail by changing the order of the constructors in the class to:
class NestedException : RuntimeException {
constructor(cause: Throwable) : super(cause)
constructor(message: String) : super(message)
constructor() : super()
}
But I don't think this is actually a good solution as it shouldn't matter the order of the constructors in my exception, it should work the same way regardless.
I think the issue is at this line where the wrong constructor is being selected (the string constructor instead of the cause constructor).