Exceptions/Catch an exception thrown in a nested call: Difference between revisions
Content added Content deleted
(specify exactly how bar gets called twice (according to the Python example which was with the task creation)) |
(add Haskell example) |
||
Line 296: | Line 296: | ||
If you have tango stack-trace, stack-trace will be print after second message. |
If you have tango stack-trace, stack-trace will be print after second message. |
||
=={{header|Haskell}}== |
|||
<lang haskell>import Control.Monad.Error |
|||
import Control.Monad.Trans (lift) |
|||
-- Our "user-defined exception" tpe |
|||
data MyError = U0 | U1 | Other deriving (Eq, Read, Show) |
|||
-- Required for any error type |
|||
instance Error MyError where |
|||
noMsg = Other |
|||
strMsg _ = Other |
|||
-- Throwing and catching exceptions implies that we are working in a monad. In |
|||
-- this case, we use ErrorT to support our user-defined exceptions, wrapping |
|||
-- IO to be able to report the happenings. ('lift' converts ErrorT e IO a |
|||
-- actions into IO a actions.) |
|||
foo = do lift (putStrLn "foo") |
|||
mapM_ (\toThrow -> bar toThrow -- the protected call |
|||
`catchError` \caught -> -- the catch operation |
|||
-- ↓ what to do with it |
|||
case caught of U0 -> lift (putStrLn "foo caught U0") |
|||
_ -> throwError caught) |
|||
[U0, U1] -- the two exceptions to throw |
|||
bar toThrow = do lift (putStrLn " bar") |
|||
baz toThrow |
|||
baz toThrow = do lift (putStrLn " baz") |
|||
throwError toThrow |
|||
-- We cannot use exceptions without at some outer level choosing what to do |
|||
-- if an exception propagates all the way up. Here we just print the exception |
|||
-- if there was one. |
|||
main = do result <- runErrorT foo |
|||
case result of |
|||
Left e -> putStrLn ("Caught error at top level: " ++ show e) |
|||
Right v -> putStrLn ("Return value: " ++ show v)</lang> |
|||
=={{header|Java}}== |
=={{header|Java}}== |