From 688c6ae2997c57d8b90c4ba49791e3c47eed3e0b Mon Sep 17 00:00:00 2001 From: Simon Marlow <marlowsd@gmail.com> Date: Fri, 12 Dec 2008 11:53:07 +0000 Subject: [PATCH] Fix a bug in catch when the handler has type (SomeException -> IO a) This was causing certain exceptions in GHC to not get caught correctly, in particular the "mismatched interface file versions" error when reading the old interface file. --- Control/Exception/Extensible.hs | 41 ++++++++++++++++++--------------- 1 file changed, 23 insertions(+), 18 deletions(-) diff --git a/Control/Exception/Extensible.hs b/Control/Exception/Extensible.hs index 988b07b..1526096 100644 --- a/Control/Exception/Extensible.hs +++ b/Control/Exception/Extensible.hs @@ -201,26 +201,31 @@ catch :: Exception e => IO a -- ^ The computation to run -> (e -> IO a) -- ^ Handler to invoke if an exception is raised -> IO a -catch io handler = io `E.catch` handler' - where handler' e = case fromException (toException e) of - Just e' -> - -- Handle the case where e == E.Exception, - -- or one of the types that make up E.Exception - handler e' - Nothing -> - case e of +catch io poly_handler = io `E.catch` handler' + where + -- First look for "new style" exceptions, which are thrown + -- as E.DynException (SomeException e) + + -- needs scoped TVs: handler' :: E.Exception -> IO a + handler' e = case e of E.DynException dyn -> case fromDynamic dyn of - Just (SomeException exc) -> - case cast exc of - Just e' -> - -- Handle the case where we have - -- a new exception type encoded - -- as a Dynamic - handler e' - Nothing -> E.throw e - Nothing -> E.throw e - _ -> E.throw e + Just se@(SomeException _) -> + case fromException se of + Just e' -> poly_handler e' + Nothing -> E.throw e + Nothing -> try_old e + _ -> try_old e + + -- If it's a legacy exception (E.Exception or one of the + -- types that make up E.Exception), check for a handler than + -- can handle them: + + -- needs scoped TVs: try_old :: E.Exception -> IO a + try_old e = case fromException (toException e) of + Just e' -> poly_handler e' + Nothing -> E.throw e + -- | When you want to acquire a resource, do some work with it, and -- then release the resource, it is a good idea to use 'bracket', -- GitLab