[Haskell-cafe] How to handle exceptions in conduit?

Michael Snoyman michael at snoyman.com
Mon Nov 5 21:10:54 CET 2012


On Mon, Nov 5, 2012 at 9:51 PM, Michael Snoyman <michael at snoyman.com> wrote:

>
> On Nov 5, 2012 2:42 PM, "Hiromi ISHII" <konn.jinro at gmail.com> wrote:
> >
> > Hi, there
> >
> > On 2012/11/01, at 21:23, Michael Snoyman wrote:
> >
> > > Due to various technical reasons regarding the nature of conduit, you
> can't currently catch exceptions within the Pipe monad. You have two
> options:
> > >
> > > * Catch exceptions before `lift`ing.
> > > * Catch exceptions thrown from the entire Pipe.
> > >
> > > Since the exceptions are always originating in the underlying monad,
> the first choice is certainly possible in theory, though may require
> reworking the library you're using a bit.
> >
> > Thanks. In my case, used library is relatively small so I can rewrite it
> to ignore exception before lifting.
> > But I think it is more convenient doing the same thing without modifying
> existing code.
> >
> > The second choice does not match my case because it cannot resume the
> process from the place just after an exception occurred.
>
> I agree that it would be great if conduit could meet your use case better.
> I haven't spent enough cycles looking at this yet to determine if the
> reason we don't have this support is a limitation in the conduit approach
> itself, or just a limitation in what I was able to implement so far. If you
> can think of a way to implement more fine-grained exception handling (or
> anyone else for that matter), I'd love to hear about it.
>
> > > One other possibility that I haven't actually tried would be to use
> transPipe[1] to catch all of the exceptions, though I'm not sure how well
> that would work in practice.
> >
> > The type of the first argument of `transPipe` should be general, so I
> think we can't compose it with `catch` function.
>
> That makes sense.
>
>
> > -- Hiromi ISHII
> > konn.jinro at gmail.com
> >
> >
> >
> >
> > _______________________________________________
> > Haskell-Cafe mailing list
> > Haskell-Cafe at haskell.org
> > http://www.haskell.org/mailman/listinfo/haskell-cafe
>
>  Sorry, small follow-up. It's certainly possible to make some kind of
catching function, e.g.:

catchPipe :: (MonadBaseControl IO m, Exception e) => Pipe l i o u m r -> (e
-> Pipe l i o u m r) -> Pipe l i o u m r
catchPipe (HaveOutput p c o) f = HaveOutput (catchPipe p f) c o
catchPipe (NeedInput p c) f = NeedInput (flip catchPipe f . p) (flip
catchPipe f . c)
catchPipe (Done r) _ = Done r
catchPipe (PipeM mp) f = PipeM $ Control.Exception.Lifted.catch (liftM
(flip catchPipe f) mp) (return . f)
catchPipe (Leftover p l) f = Leftover (catchPipe p f) l

I'm just not certain how useful this is in practice, as it doesn't really
give you any information on what else that Pipe was about to perform. So
you can't really just pick up where you left off.

Michael
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/haskell-cafe/attachments/20121105/52427c0f/attachment.htm>


More information about the Haskell-Cafe mailing list