
#12750: hGetContents leads to late/silent failures -------------------------------------+------------------------------------- Reporter: massimo.zaniboni | Owner: Type: bug | Status: new Priority: normal | Milestone: Component: Core Libraries | Version: 8.0.1 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: Incorrect result | Test Case: at runtime | https://github.com/massimo- | zaniboni/ghc_lazy_file_content_error Blocked By: | Blocking: Related Tickets: #9236 | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by massimo.zaniboni): Replying to [comment:2 rwbarton]:
Indeed, mixing `hGetContents` and `bracket` isn't recommended.
I like lazy functions like `Data.Text.Lazy.hGetContents` because I can process file content chunk by chunk using a constant amount of RAM, and the code is very elegant. In any case the problem is related to any type of lazy evaluation using a resource managed by `bracket`, so not only `hGetContents`. More clearly there are two bugs: 1) when the code reads the content of a closed file handle, instead of returning a run-time exception, a normal EOF is returned, and the application code has a bad behavior, because normal code path is executed instead of processing the exception. 2) `bracket` does not work well with resources processed in a lazy way, because the thunk using the resource can be used after `bracket` has closed it, generating unexpected run-time errors. So the best semantic of `bracket` should be a strict evaluation of the result. It is a behavior more predictable and similar to Resource Acquisition Is Initialization (RAII) semantic of C++. But probably this is not the best place for signaling this. By the way I solved the problem executing with strict semantic all the file processing instructions inside `bracket`. File content is still processed chunk by chunk, but the handle is closed only at the end, when the result is returned. So my work-around rule is: use `bracket` only with strict semantic. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/12750#comment:3 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler