What is a good way to wrap a conduit in ExceptT
? The approach should stop the processing when there is an error, and extract the error message. Here is a toy code without error-handling - it just silently stops:
import Data.Conduit as C
import Data.ByteString as BS
import Control.Monad
import Control.Monad.IO.Class
import Data.Text as T
-- just a dummy processing to simulate errors
process :: BS.ByteString -> Either (Int,T.Text) BS.ByteString
process inp = if (BS.null inp) then Left $ (1,"Empty input") else Right inp
-- silent processing - stops on error but doesn't tell us what it is
sink :: MonadIO m => Consumer BS.ByteString m ()
sink = do
bs <- await
case bs of
Just val -> do
let msg = process val
case msg of
Left _ -> return ()
Right x -> (liftIO $ return x) >> sink
Nothing -> return ()
How could we change the type signature of sink
to something like below?
sink :: MonadIO m => ExceptT e m (Consumer BS.ByteString m ())
In case of Left
, it will be nice to break out of the pipeline, and return the error message to top.
I read this blog post but haven't understood it well enough yet to apply it to conduit (which also has complicated type signature). I will like to apply the proposed approach here to conduit - it seems EitherT
suggested in the approach has now been subsumed by ExceptT
.