I have a monad transformer stack that looks like this (for some user-defined types R
, S
and E
):
EitherT[RWST[IO, R, Unit, S, ?], E, ?]
I used to be very rigorous when using this, in wrapping Java calls such that any thrown exceptions would be caught at turned into an E
of my choosing. This kind of thing:
MyStack.fromTryCatch( javaApi.foo(), t => FooFailed(t) )
Over a (not very long) period, I realied that I was on a hiding to nothing: I would inevitably miss wrapping some calls and, even more inevitably, these calls would occasionally fail by throwing exceptions [1]. These would bubble up out of my stack and ... DISAPPEAR!
That's fine, though. "Let it crash" and all that. Except that often the programs would not crash. Because exceptions had bubbled out of my stack, resources were not freed and non-daemon threads would be hanging around, the rest of my program clinging on for dear life. There may be no exceptions in the logs, nothing! How could there be, my program having