Exceptions/Catch an exception thrown in a nested call: Difference between revisions

add Haskell example
(specify exactly how bar gets called twice (according to the Python example which was with the task creation))
(add Haskell example)
Line 296:
 
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}}==