From: Simon Marlow Date: Mon, 12 Oct 2009 15:29:55 +0000 (+0000) Subject: Make hGetContents throw an exception if an error is encountered X-Git-Url: http://git.megacz.com/?p=ghc-base.git;a=commitdiff_plain;h=d9b146b931c749029a914cd70a2ff109b83784dc Make hGetContents throw an exception if an error is encountered Strictly speaking this breaks Haskell 98 compatibility, which requires hGetContents to just end the lazy stream silently if an error is encountered. However, for a few reasons we think it will make everyone's life a bit easier if we make this change 1. Errors will be a lot more common in GHC 6.12.1, in the form of Unicode decoding errors. 2. When Haskell 98 was designed, we didn't know how to throw exceptions from inside lazy I/O, but now we do. 3. If anyone is actually relying on the previous behaviour, their code is arguably broken. --- diff --git a/GHC/IO/Handle/Text.hs b/GHC/IO/Handle/Text.hs index ed3a106..ebbacd4 100644 --- a/GHC/IO/Handle/Text.hs +++ b/GHC/IO/Handle/Text.hs @@ -355,12 +355,12 @@ hGetContents handle = lazyRead :: Handle -> IO String lazyRead handle = unsafeInterleaveIO $ - withHandle "lazyRead" handle $ \ handle_ -> do + withHandle "hGetContents" handle $ \ handle_ -> do case haType handle_ of ClosedHandle -> return (handle_, "") SemiClosedHandle -> lazyReadBuffered handle handle_ _ -> ioException - (IOError (Just handle) IllegalOperation "lazyRead" + (IOError (Just handle) IllegalOperation "hGetContents" "illegal handle type" Nothing Nothing) lazyReadBuffered :: Handle -> Handle__ -> IO (Handle__, [Char]) @@ -377,14 +377,15 @@ lazyReadBuffered h handle_@Handle__{..} = do writeIORef haCharBuffer (bufferAdjustL r buf') return (handle_, s) ) - -- all I/O errors are discarded. Additionally, we close the handle. (\e -> do (handle_', _) <- hClose_help handle_ debugIO ("hGetContents caught: " ++ show e) -- We might have a \r cached in CRLF mode. So we -- need to check for that and return it: - if not (isEmptyBuffer buf) - then return (handle_', "\r") - else return (handle_', "") + if isEOFError e + then if not (isEmptyBuffer buf) + then return (handle_', "\r") + else return (handle_', "") + else ioError e ) -- ensure we have some characters in the buffer