How to properly handle an IOException from close()

前端 未结 9 1563
滥情空心
滥情空心 2021-02-05 08:14

The Java I/O classes java.io.Reader, java.io.Writer, java.io.InputStream, java.io.OutpuStream and their various subclasses al

9条回答
  •  悲&欢浪女
    2021-02-05 08:34

    "Ignoring or just logging is usually a bad idea." That's not answering the question. What should one do about an IOException from close()? Just rethrowing it only pushes the problem further up, where it's even more difficult to handle.

    Theory

    To answer you question directly: When this IO action failed, then depending on the circumstances, you may want to

    • rollback changes (don't leave a partially written file on the disk, delete it)
    • retry (maybe after a rollback)
    • ignore (and continue)
    • interrupt the current task (cancel)

    You can often see the last 3 in dialog boxes shown to the user. Indeed, delegating choice to the user is a possibility.

    I believe the main point is to not leave the system in an inconsistent state. Just swallowing a close exception might leave you with a crippled file, causing nasty errors later on.

    Practice

    It is a bit cumbersome to work with checked exceptions. Options arise:

    • Convert them to RuntimeException, throw them and leave them to be handled at a sufficiently high level

    • Keep using checked exceptions and suffer the syntactic pain

    • Use more composable error handling constructs, like the IO monad (not really available in Java, at least not without embarassingly many braces (see http://apocalisp.wordpress.com/2008/05/16/thrower-functor/) and not with full power)

    More on IO monad

    When you return a result in the IO monad context, you are not actually executing an IO action, but rather return the description of that action. Why? These actions have an API with which they compose nicely (versus the throws/try/catch massacre).

    You can decide if you wish to do check exception style handling (with Option or Validation˙ in the return type), or dynamic style handling, with bracketing only on the finalunsafePerformIO` call (which actually executes the composed IO action).

    To get some idea, see my Scala gist http://gist.github.com/2709535, which hosts the executeAndClose method. It returns both the result of the resource processing (if available) and an unclosed resource (if closing failed). It is then the users decision how to deal with such an unclosable resource.

    It could be beefed up with Validation/ValidationNEL instead of Option if one needs the one/more actual exceptions too.

提交回复
热议问题