def ints: IO[Int] = 3.pure[IO].handleErrorWith(e => 4.pure[IO])
// this is handleError
def string: IO[String] = (ints <* boom).map(_.toString)
// if handleErrorWith worked here you'd try to return an Int instead of a String
handleErrorWith
installed a handler which is valid for all IOs flatMapped after this, which type should it return?
IO[Nothing]
, which can only be something that never terminates (IO cannot emit zero values)
catch
IO.unit.handleError(...) >> boom
, which doesn't handle errors in boom
try {
thing
} catch {
...
}
boom
doesn't handle errors in boom
readFile.timeout(5.seconds)
(assuming that your readfile implementation is cancelable)
.join
if you haven't called cancel
. In the simplest case this is an if, in more complicated cases you might need some coordination between the interrupter and the joiner
Deferred[Option[Thing]]
bracketCase
or guaranteeCase
the started operation so that it puts None
on that Deferred
when it gets cancelled