Generalizing Network.CGI exceptions to MonadCatchIO

A few things have frustrated me about Network.CGI’s exception handling.
• I can’t use the new-style Exception class directly; I have to convert to
and from SomeException first.
• There’s no analogue of nice utilities like bracket and onException for
CGI.
• I can only use throwCGI and catchCGI in CGIT IO, not an arbitrary
MonadCGI.
One way to solve all three of these problems is using MonadCatchIO. As an
added bonus, we get a much simpler definition of try/catch.
Who is maintaining the CGI library these days? What do you think of this
patch?
(It would be possible to generalize the types even further, from
SomeException to Exception e => e, but I’m worried about introducing
ambiguous type variables into existing code. After this patch, new code
can just use the Control.Monad.CatchIO functions directly to deal with
Exception e => e.)
Anders
-- 8< --
From 5f9b9ca5e9faf34b36887737d820c3ca9ea76e09 Mon Sep 17 00:00:00 2001
From: Anders Kaseorg

On Mon, Mar 15, 2010 at 8:37 PM, Anders Kaseorg
(It would be possible to generalize the types even further, from SomeException to Exception e => e, but I’m worried about introducing ambiguous type variables into existing code. After this patch, new code can just use the Control.Monad.CatchIO functions directly to deal with Exception e => e.)
(Note I'm not a user of the cgi package so don't take the following to seriously) What about deprecating all the cgi exception handling functions: throwCGI, catchCGI and tryCGI in favor of the CatchIO ones? The advantage: a simpler API. The disadvantage: possible ambiguous type variables like you mentioned. However, these can usually be resolved using a simple type annotation in your exception handler. Maybe somebody can analyze the reverse dependencies of cgi to see if any ambiguities will actually arise: http://bifunctor.homelinux.net/~roel/cgi-bin/hackage-scripts/revdeps/cgi-300... regards, Bas P.S. It would also be a good idea to rename the section "Error handling" to "Exception handling" because of: http://haskell.org/haskellwiki/Error_vs._Exception

On Mon, 15 Mar 2010, Bas van Dijk wrote:
What about deprecating all the cgi exception handling functions: throwCGI, catchCGI and tryCGI in favor of the CatchIO ones?
Yeah, that’s basically the direction I want to go in. This patch makes the new CatchIO functions work by adding a MonadCatchIO interface, without breaking the old ones (though the old ones get a little bit of generalization for free).
The advantage: a simpler API.
The disadvantage: possible ambiguous type variables like you mentioned.
Since CGI doesn’t currently have a MonadCatchIO interface at all, that can’t be a compatibility problem. (I checked anyway, just to be sure that none of the existing packages declare their own MonadCatchIO interface that would conflict with the one I’m adding. There’s only one package (bff) that recursively depends on both cgi and MonadCatchIO, and it doesn’t mention MonadCatchIO directly.) Anders

On Mon, Mar 15, 2010 at 9:59 PM, Anders Kaseorg
On Mon, 15 Mar 2010, Bas van Dijk wrote:
What about deprecating all the cgi exception handling functions: throwCGI, catchCGI and tryCGI in favor of the CatchIO ones?
Yeah, that’s basically the direction I want to go in. This patch makes the new CatchIO functions work by adding a MonadCatchIO interface, without breaking the old ones (though the old ones get a little bit of generalization for free).
Yes we should do that. But in addition we can advice the users of catchCGI to actually use the CatchIO.catch instead by adding a deprecated pragma like: {-# DEPRECATED catchCGI "Use Control.Monad.CatchIO.catch instead." #-} Or is this to rude? Something else: which MonadCatchIO package are you proposing to use: MonadCatchIO-mtl or MonadCatchIO-transformers? I guess the former because cgi depends on mtl. In that case we should contact the maintainer of MonadCatchIO-mtl and ask if he can add the following functions: bracket_, bracketOnError and finally (types and definitions below). Then the API is equivalent to Control.Exception. (I CCed this message to the maintainer) (I wrote a patch a while ago that added these to MonadCatchIO-transformers because I needed them in my regions package. But they are not present in MonadCatchIO-mtl) regards, Bas -- | A variant of 'bracket' where the return value from the first computation -- is not required. bracket_ :: MonadCatchIO m => m a -- ^ computation to run first (\"acquire resource\") -> m b -- ^ computation to run last (\"release resource\") -> m c -- ^ computation to run in-between -> m c -- returns the value from the in-between computation bracket_ before after thing = block $ do before r <- unblock thing `onException` after after return r -- | A specialised variant of 'bracket' with just a computation to run -- afterward. finally :: MonadCatchIO m => m a -- ^ computation to run first -> m b -- ^ computation to run afterward (even if an exception was -- raised) -> m a -- returns the value from the first computation thing `finally` after = block $ do r <- unblock thing `onException` after after return r -- | Like 'bracket', but only performs the final action if there was an -- exception raised by the in-between computation. bracketOnError :: MonadCatchIO m => m a -- ^ computation to run first (\"acquire resource\") -> (a -> m b) -- ^ computation to run last (\"release resource\") -> (a -> m c) -- ^ computation to run in-between -> m c -- returns the value from the in-between computation bracketOnError before after thing = block $ do a <- before unblock (thing a) `onException` after a

On Mon, 15 Mar 2010, Bas van Dijk wrote:
But in addition we can advice the users of catchCGI to actually use the CatchIO.catch instead by adding a deprecated pragma like:
{-# DEPRECATED catchCGI "Use Control.Monad.CatchIO.catch instead." #-}
Or is this to rude?
I’d have no objection to that, if the maintainer agrees.
Something else: which MonadCatchIO package are you proposing to use: MonadCatchIO-mtl or MonadCatchIO-transformers? I guess the former because cgi depends on mtl.
Right, one change at a time. :-)
In that case we should contact the maintainer of MonadCatchIO-mtl and ask if he can add the following functions: bracket_, bracketOnError and finally (types and definitions below).
Sure, those would definitely be nice to have regardless. Anders

Thanks for showing the cgi package some love. It really needs a new
maintainer since I have no time to spend on it. I think Ganesh was
looking into that. Any news?
/Bjorn
On Mon, Mar 15, 2010 at 21:56, Anders Kaseorg
On Mon, 15 Mar 2010, Bas van Dijk wrote:
But in addition we can advice the users of catchCGI to actually use the CatchIO.catch instead by adding a deprecated pragma like:
{-# DEPRECATED catchCGI "Use Control.Monad.CatchIO.catch instead." #-}
Or is this to rude?
I’d have no objection to that, if the maintainer agrees.
Something else: which MonadCatchIO package are you proposing to use: MonadCatchIO-mtl or MonadCatchIO-transformers? I guess the former because cgi depends on mtl.
Right, one change at a time. :-)
In that case we should contact the maintainer of MonadCatchIO-mtl and ask if he can add the following functions: bracket_, bracketOnError and finally (types and definitions below).
Sure, those would definitely be nice to have regardless.
Anders

I was actually looking into the maintainership of xhtml, though I do care about cgi too and the same logic (of choosing a maintainer) may well apply to both. In any case the last news is that I emailed libraries@ asking if it was appropriate for it to be maintained there given that it used to be distributed by GHC, but noone has replied so the situation is somewhat stalled. Bjorn Bringert wrote:
Thanks for showing the cgi package some love. It really needs a new maintainer since I have no time to spend on it. I think Ganesh was looking into that. Any news?
/Bjorn
On Mon, Mar 15, 2010 at 21:56, Anders Kaseorg
wrote: On Mon, 15 Mar 2010, Bas van Dijk wrote:
But in addition we can advice the users of catchCGI to actually use the CatchIO.catch instead by adding a deprecated pragma like:
{-# DEPRECATED catchCGI "Use Control.Monad.CatchIO.catch instead." #-}
Or is this to rude?
I'd have no objection to that, if the maintainer agrees.
Something else: which MonadCatchIO package are you proposing to use: MonadCatchIO-mtl or MonadCatchIO-transformers? I guess the former because cgi depends on mtl.
Right, one change at a time. :-)
In that case we should contact the maintainer of MonadCatchIO-mtl and ask if he can add the following functions: bracket_, bracketOnError and finally (types and definitions below).
Sure, those would definitely be nice to have regardless.
Anders
=============================================================================== Please access the attached hyperlink for an important electronic communications disclaimer: http://www.credit-suisse.com/legal/en/disclaimer_email_ib.html ===============================================================================

On Tue, 16 Mar 2010, Bjorn Bringert wrote:
Thanks for showing the cgi package some love. It really needs a new maintainer since I have no time to spend on it. I think Ganesh was looking into that. Any news?
With Ganesh’s approval, I’ve declared myself maintainer of the cgi library. I uploaded two new versions. 3001.1.7.3 just fixes two regressions in 3001.1.7.2: • Don’t use non-standard pattern guards. • Restore compatibility with base-3 using extensible-exceptions. 3001.1.8 extends the API by adding a MonadCatchIO instance as I proposed. (I’m going to hold off on formally deprecating throwCGI, catchCGI, tryCGI for now, pending some thinking about how best to reconcile the cgi API with Dan Knapp’s new direct-fastcgi API.) Anders
participants (4)
-
Anders Kaseorg
-
Bas van Dijk
-
Bjorn Bringert
-
Sittampalam, Ganesh