in reply to @ 2016-003.913ZFor a while I put syncIO from the errors package everywhere
Yeah. If you want to be extra paranoid then syncIO from https://hackage.haskell.org/package/unexceptionalio-0.2.0/docs/UnexceptionalIO.html is your friend. Forces you to never forget it anywhere. Then handle anything reasonable at the call site and propagate anything that needs to be with a differentiated type.
People like to hate on the typed exceptions in Java, but the issue there is the lack of type inference really.
None of this will help you with async exceptions or programmer errors, but those need to be handled in a different way anyway.