Inconsistent cancellation and lost exceptions
See original GitHub issueConsider following snippet:
val job = async() {
barrier.await()
throw IOException()
}
barrier.await()
job.cancel(TestException())
job.await() // <- 1
1
will always throw IOException
and it will have eitherCompletedExceptionally
or Cancelled
state. TestException
is always lost even when cancel
call was successful.
Now slightly rewrite it:
val job = async() {
barrier.await()
withContext(wrapperDispatcher(coroutineContext)) { // Just a wrapper to avoid fast paths in implementation
throw IOException()
}
}
barrier.await()
job.cancel(TestException())
job.await() // <- 2
Now 2
now can throw JobCancellationException: Job is being cancelled
which definitely shouldn’t be a terminal exception. Depending on timing it also may lose either TestException
or IOException
(even when its known that IOException
was thrown).
What user may expect
- When it’s known that
IOException
was thrown,await()
should throw it as well. If concurrent cancellation with the cause was successful,IOException
should have its cause as suppressed exception - When it’s known that
IOException
wasn’t thrown (cancellation was “first”),await
should throwTestException
JobCancellationException
should never be thrown if the cause is present on all code paths and the job is in its final state- No intermediate
JobCancellationException
should be present in the final state ofJob
We should design, rework and document exception handling mechanism. We can give up some performance on an exceptional path (especially when multiple exceptions are thrown), but regular code path should stay the same
Issue Analytics
- State:
- Created 5 years ago
- Comments:12 (9 by maintainers)
Top Results From Across the Web
Recommended patterns for CancellationToken
If you've experienced cancellation before, you've probably noticed a couple of types of these exceptions: TaskCanceledException and ...
Read more >Inconsistent exception details in parallel stream - Stack Overflow
If the task is executed on a thread pool thread, the exception is caught, the other tasks are canceled, and the exception is...
Read more >Uncaught Exception Crash? | Apple Developer Forums
"An uncaught exception was raised. Choose "Continue" to continue running in an inconsistent state. Choose "Crash" to halt the application and file a...
Read more >Top 15 C++ Exception handling mistakes and how to avoid ...
Think about what you're losing out by not using exceptions. If you hit a performance / size bottleneck, think about scaling out rather...
Read more >Textbook Rental Terms & Conditions - Amazon.com
We are not responsible for items that are lost in transit from you to us or for ... We reserve the right to...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
I was able to force-throw an exception out of the coroutine on android using the main thread
Handler
.@bolein I will update our guide before merging it. The general idea is to make exception handling “synchronous” to make parallel decomposition transparent.
E.g. for code
MyExceptionHandler
will receive one of the exceptions (depending on timing) and another one in suppressed exceptions. For jobs hierarchy exception is reported only once by root job, having all intermediate exceptions as suppressed, exceptions are never swallowed.Other changes:
JobCancellationException
are always ignored and used for internal machineryNote that it’s work in progress and anything can change.
It’s going into release as soon as it’s ready. It has a lot of corner cases and is breaking change, so we should internally evaluate it first.