I have three functions I map over, I wish to stop evaluation upon catching an exception.
I can catch the exception, but am not getting the behavior I want. It could be that I’m thinking about this problem in the incorrect way (maybe I shouldn’t be map a list of functions in this case), and would appreciate this being pointed out. Here’s what I think is the relevant code.
import qualified Control.Exception as C
data JobException = PreProcessFail
| JobFail
| ChartFail
deriving (Show, Typeable)
instance C.Exception JobException
type ProcessState = MVar ProcessConfig
data ProcessConfig = PConfig { model :: ServerModel
, ipAddress :: String
, cookie :: Cookie
} deriving Show
exceptionHandler :: JobException -> IO ()
exceptionHandler exception = do
writeFile "testException.txt" ("caught exception " ++ (show exception))
-- much more functionality will be put here once I get the logic correct
preProcess :: ProcessState -> IO ()
preProcess sModel = do
putStrLn ("preProcessing" )
initiateJob :: ProcessState -> IO ()
initiateJob sModel = do
C.throw JobFail
putStrLn ("in progress")
makeChart :: ProcessState -> IO ()
makeChart sModel = do
putStrLn ("chart making")
So now, when I test this out in ghci, this is what happens.
a <- mapM (flip Control.Exception.catch exceptionHandler) [preProcess world, initiateJob world, makeChart world]
Loading package filepath-1.2.0.0 ... linking ... done.
Loading package unix-2.4.2.0 ... linking ... done.
preProcessing
chart making
I should not be seeing the string “chart making”. How do I abort the evaluation of the list upon throwing an exception?
mapMmaps the function then sequences the list. So you’ve got acatcharound each action in the list separately. What you want is to sequence the list into a single action, and then catch the exception once so interrupting everything else in the list. The following works: