Open
Description
I can't quite figure out how to catch decompression errors. I'd expect the usual mechanisms, try
or catch
, to work. But LzmaRet
Exceptions thrown by decompress
cannot be caught. Here's my example (create a jumbled.xz
file with silly content):
{-# LANGUAGE OverloadedStrings #-}
module Main where
import qualified Codec.Compression.Lzma as Lzma
import Control.Exception (catch)
import qualified Data.ByteString.Lazy as BSL
readXz :: FilePath -> IO BSL.ByteString
readXz f = do
let params = Lzma.defaultDecompressParams {Lzma.decompressMemLimit = maxBound}
Lzma.decompressWith params <$> BSL.readFile f
handleErr :: Lzma.LzmaRet -> IO BSL.ByteString
handleErr e = do
print e
return ""
main :: IO ()
main = do
a <- catch (readXz "jumbled.xz") handleErr
print a
This will not fail gracefully. What am I missing, here?
Activity
hvr commentedon Apr 15, 2018
A transformer acting on lazy bytestrings and returning a lazy bytestring simply has no ability to signal errors in a well-defined way. This is a fundamental issue w/ lazy
ByteString
s. AlsoBSL.readFile
suffers from this issue: some I/O errors may result in exceptions being injected into lazy bytestring chunks.If you need the ability to handle errors in a well-defined way you should use the incremental api, e.g.
compressIO
orcompressST
; or alternatively take a look at the streaming framework bindings mentioned at http://hackage.haskell.org/package/lzma.