
On Fri, 24 Jan 2003, Sarah Thompson wrote:
I've noticed some interesting behaviour:
Prelude Control.Exception> try (return (error "e")) Prelude Control.Exception> it Right *** Exception: e
It would appear that when the result of this function is evaluated, the exception fires during evaluation, after the try is out of scope. I suppose it makes some kind of twisted sense due to lazy evaluation going on, but it is certainly a gotcha.
I did notice this:
Prelude Control.Exception> try (return $! (error "e")) Prelude Control.Exception> it Left e
Seemingly, forcing strict evaluation on the argument of return fixes the problem by making sure that any exception that *can* happen, *does* happen.
However, this code from my COM wrapper:
--[id(3)] HRESULT XmlQuery([in,string] BSTR query, [out,retval]BSTR* xml); xmlQuery :: String -> State -> IO String xmlQuery qry (State st) = do db <- readIORef st Control.Exception.catch (return $! (XMLDatabase.xmlQuery qry db)) (\ _ -> return "
") doesn't work. If XMLDatabase.xmlQuery throws an exception, the COM wrapper still terminates the host application (Yes, Sigbjorn - I did apply your patch to HDirect, but it seemed to make no difference).
Your COM wrapper code probably behaves differently because the error is not evoked at the very top level. Note that `seq` (and hence ($!)) only force evaluation to "weak head normal form", which essentially means only enough to determine the top-level constructor. You may need to evaluate more deeply. Check out `DeepSeq` (http://haskell.org/pipermail/haskell/2001-August/001586.html) and/or "strategies" (http://www.mail-archive.com/haskell@haskell.org/msg09543/Strategies.lhs).
I'm still a bit stuck here!
Sarah
Dean