typelevel / typelevel/cats-effect
unsafeToFuture fails to raise a second InterruptedException if the exception is handled and retried
Nobody has claimed this yet.
- Dominant language
- Scala
- Stars
- 2.2k
- Forks
- 576
- Avg merge
- 2d 11h
- Merged PRs (30d)
- 18
Description
The code below catches a ExecutionException which wraps the Interrupted exception on the first iteration. On the second iteration no ExecutionException is thrown and the main thread blocks on the Await.
while(true){
val f = IO{
throw new InterruptedException("Test")
}.attempt.unsafeToFuture()(IORuntime.global)
try{
Await.result(f, Duration.Inf)
} catch {
case t:ExecutionException => println(s"Underlyng exception ${t.getCause}")
}
}
I think the issue is in IOFiber.onFatalFailure specifically the line
if (IORuntime.globalFatalFailureHandled.compareAndSet(false, true))
On the first iteration globalFatalFailureHandled is initialised to false on the second iteration its now true so the code
block is never executed and the exception isn't raised.
If that is the case would adding a function like resetFatalFailureHandled be added to IORuntime to reset it if the future returned from unsafeToFuture has its ExecutionException handled and retried in a loop?
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the reproduction using IO.unsafeToFuture, Await.result, and the retry loop, then inspect IOFiber.onFatalFailure and IORuntime.globalFatalFailureHandled. Confirm the first iteration's handled ExecutionException changes subsequent behavior; done means repeated iterations consistently surface the interruption rather than block, with the runtime behavior verified against the proposed handling path.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- scala
- Domain
- backend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100