无法从管道中的错误中恢复

Unable to recover from errors in Conduit

我正在尝试了解如何捕获管道中抛出的错误。我相信通过在管道上应用 catchC,我可以生成一个新的管道,它会在发生故障时重新运行。

在下面的示例中,我们有一个源,它会根据布尔值抛出自定义虚拟异常。最初,该布尔值的值导致抛出该异常,但是 catchC 中的处理程序会产生一个新的管道,该管道应表现出相反的行为(产生从 1 到 10 的数字)

{-# LANGUAGE DeriveDataTypeable #-}

module Main where

import Data.Conduit
import qualified Data.Conduit.List as CL
import Control.Monad.IO.Class
import Control.Exception
import Data.Typeable

data MyException = MyException String
    deriving (Show, Typeable)

instance Exception MyException where

listAsStream :: Bool -> Source IO Int
listAsStream val =  if val then CL.sourceList [1..10] else throw $ MyException "Value"

conduitWhatever :: Sink Int IO ()
conduitWhatever = awaitForever $ liftIO . print

main :: IO ()
main = catchC (listAsStream False) handler $$ conduitWhatever

handler :: MyException -> Source IO Int
handler _= catchC (listAsStream True) handler

我很确定我误解了 catchC 的工作原理。谁能解释一下我做错了什么?

非常感谢!

您对catchC的用法是正确的;问题是 throw 的使用,它引入了一个不精确的异常而不是适当的 IO 异常。如果您改用:

liftIO $ throwIO $ MyException "Value"

您的程序按预期运行。