[GHC] #9236: hGetContents leads to late/silent failures

#9236: hGetContents leads to late/silent failures ------------------------------------+------------------------------------- Reporter: dfeuer | Owner: Type: feature request | Status: new Priority: normal | Milestone: Component: Compiler | Version: 7.6.3 Keywords: | Operating System: Unknown/Multiple Architecture: Unknown/Multiple | Type of failure: None/Unknown Difficulty: Unknown | Test Case: Blocked By: | Blocking: Related Tickets: | ------------------------------------+------------------------------------- A common newbie error: {{{ #!haskell withFile "file" ReadMode hGetContents >>= putStr }}} The problem, of course, is that the result of `withFile "file" ReadMode hGetContents` isn't forced until `putStr` is executed, at which point the file has already been closed. The Haskell report doesn't specify what it will find, and, at least in 7.6.3, it finds the string empty. The behavior that seems most correct to me would be to guarantee that if a file has not been completely read (or read up to an I/O error) when it is closed, then its contents should be reported as something like `"Four score and seven years ag"++error "Forcing a suspended computation led to an attempted read from a handle that was already closed."` Since the current system apparently puts an `[]` as a temporary marker while waiting to see what the rest of the list will be, I imagine that the fix is as simple as putting the error thunk there instead. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9236 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9236: hGetContents leads to late/silent failures -------------------------------------+------------------------------------ Reporter: dfeuer | Owner: Type: feature request | Status: new Priority: normal | Milestone: Component: Compiler | Version: 7.6.3 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: Unknown/Multiple Type of failure: None/Unknown | Difficulty: Unknown Test Case: | Blocked By: Blocking: | Related Tickets: -------------------------------------+------------------------------------ Comment (by dfeuer): Specifically, it looks like all that we need is to change {{{ #!haskell lazyRead :: Handle -> IO String lazyRead handle = unsafeInterleaveIO $ withHandle "hGetContents" handle $ \ handle_ -> do case haType handle_ of ClosedHandle -> return (handle_, "") SemiClosedHandle -> lazyReadBuffered handle handle_ _ -> ioException (IOError (Just handle) IllegalOperation "hGetContents" "illegal handle type" Nothing Nothing) }}} to {{{ #!haskell lazyRead :: Handle -> IO String lazyRead handle = unsafeInterleaveIO $ withHandle "hGetContents" handle $ \ handle_ -> do case haType handle_ of ClosedHandle -> return (handle_, error "You can't get blood from a stone.") SemiClosedHandle -> lazyReadBuffered handle handle_ _ -> ioException (IOError (Just handle) IllegalOperation "hGetContents" "illegal handle type" Nothing Nothing) }}} -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9236#comment:1 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9236: hGetContents leads to late/silent failures -------------------------------+------------------------------------------- Reporter: dfeuer | Owner: Type: feature | Status: new request | Milestone: Priority: normal | Version: 7.8.2 Component: | Keywords: libraries/base | Architecture: Unknown/Multiple Resolution: | Difficulty: Easy (less than 1 hour) Operating System: | Blocked By: Unknown/Multiple | Related Tickets: Type of failure: Other | Test Case: | Blocking: | -------------------------------+------------------------------------------- Changes (by dfeuer): * failure: None/Unknown => Other * cc: hvr, ekmett (added) * component: Compiler => libraries/base * difficulty: Unknown => Easy (less than 1 hour) * version: 7.6.3 => 7.8.2 Old description:
A common newbie error: {{{ #!haskell withFile "file" ReadMode hGetContents >>= putStr }}}
The problem, of course, is that the result of `withFile "file" ReadMode hGetContents` isn't forced until `putStr` is executed, at which point the file has already been closed. The Haskell report doesn't specify what it will find, and, at least in 7.6.3, it finds the string empty. The behavior that seems most correct to me would be to guarantee that if a file has not been completely read (or read up to an I/O error) when it is closed, then its contents should be reported as something like `"Four score and seven years ag"++error "Forcing a suspended computation led to an attempted read from a handle that was already closed."` Since the current system apparently puts an `[]` as a temporary marker while waiting to see what the rest of the list will be, I imagine that the fix is as simple as putting the error thunk there instead.
New description: A common newbie error: {{{ #!haskell withFile "file" ReadMode hGetContents >>= putStr }}} The problem, of course, is that the result of `withFile "file" ReadMode hGetContents` isn't forced until `putStr` is executed, at which point the file has already been closed. The Haskell report doesn't specify what it will find, and, at least in 7.6.3, it finds the string empty. The behavior that seems most correct to me would be to guarantee that if a file has not been completely read (or read up to an I/O error) when it is closed, then its contents should be reported as something like `"Four score and seven years ag"++error "Forcing a suspended computation led to an attempted read from a handle that was already closed."` My suggested fix is in a comment below. -- -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9236#comment:2 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9236: hGetContents leads to late/silent failures -------------------------------+------------------------------------------- Reporter: dfeuer | Owner: Type: feature | Status: new request | Milestone: Priority: normal | Version: 7.8.2 Component: | Keywords: libraries/base | Architecture: Unknown/Multiple Resolution: | Difficulty: Easy (less than 1 hour) Operating System: | Blocked By: Unknown/Multiple | Related Tickets: Type of failure: Other | Test Case: | Blocking: | -------------------------------+------------------------------------------- Changes (by oerjan): * cc: oerjan (added) Comment: I think any error message should include the handle name. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9236#comment:3 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9236: hGetContents leads to late/silent failures -------------------------------+------------------------------------------- Reporter: dfeuer | Owner: dfeuer Type: feature | Status: new request | Milestone: Priority: normal | Version: 7.8.2 Component: | Keywords: libraries/base | Architecture: Unknown/Multiple Resolution: | Difficulty: Easy (less than 1 hour) Operating System: | Blocked By: Unknown/Multiple | Related Tickets: #8213 Type of failure: Other | Test Case: | Blocking: | -------------------------------+------------------------------------------- Changes (by dfeuer): * owner: => dfeuer * related: => #8213 -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9236#comment:4 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9236: hGetContents leads to late/silent failures -------------------------------------+------------------------------------- Reporter: dfeuer | Owner: Type: feature | Status: new request | Milestone: Priority: normal | Version: 7.8.2 Component: | Keywords: libraries/base | Architecture: Unknown/Multiple Resolution: | Difficulty: Easy (less than 1 Operating System: | hour) Unknown/Multiple | Blocked By: Type of failure: Other | Related Tickets: #8213 Test Case: | Blocking: | Differential Revisions: | -------------------------------------+------------------------------------- Changes (by dfeuer): * owner: dfeuer => Comment: Not sure I know enough about the depths of this part of the system to own the ticket. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9236#comment:5 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9236: hGetContents leads to late/silent failures -------------------------------------+------------------------------------- Reporter: dfeuer | Owner: ekmett Type: feature | Status: new request | Milestone: Priority: normal | Version: 7.8.2 Component: Core | Keywords: Libraries | Architecture: Unknown/Multiple Resolution: | Difficulty: Easy (less than 1 Operating System: | hour) Unknown/Multiple | Blocked By: Type of failure: Other | Related Tickets: #8213 Test Case: | Blocking: | Differential Revisions: Phab:D327 | -------------------------------------+------------------------------------- Changes (by dfeuer): * cc: core-libraries-committee@… (added) * differential: => Phab:D327 Comment: I decided to try this out, and it seems to work. In particular, it did ''not'' cause problems with broken pipes, and it ''did'' find a bug in Haddock. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9236#comment:7 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9236: hGetContents leads to late/silent failures
-------------------------------------+-------------------------------------
Reporter: dfeuer | Owner: ekmett
Type: feature | Status: new
request | Milestone:
Priority: normal | Version: 7.8.2
Component: Core | Keywords:
Libraries | Architecture: Unknown/Multiple
Resolution: | Difficulty: Easy (less than 1
Operating System: | hour)
Unknown/Multiple | Blocked By:
Type of failure: Other | Related Tickets: #8213
Test Case: |
Blocking: |
Differential Revisions: Phab:D327 |
-------------------------------------+-------------------------------------
Comment (by Austin Seipp

#9236: hGetContents leads to late/silent failures -------------------------------------+------------------------------------- Reporter: dfeuer | Owner: ekmett Type: feature | Status: closed request | Milestone: Priority: normal | Version: 7.8.2 Component: Core | Keywords: Libraries | Architecture: Unknown/Multiple Resolution: fixed | Difficulty: Easy (less than 1 Operating System: | hour) Unknown/Multiple | Blocked By: Type of failure: Other | Related Tickets: #8213 Test Case: | Blocking: | Differential Revisions: Phab:D327 | -------------------------------------+------------------------------------- Changes (by thomie): * status: new => closed * resolution: => fixed -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9236#comment:9 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler
participants (1)
-
GHC