;; Phase 16 — Exception handling unit tests. (hk-test "catch — success path returns the action result" (hk-deep-force (hk-run "main = catch (return 42) (\\(SomeException m) -> return 0)")) (list "IO" 42)) (hk-test "catch — error caught, handler receives message" (hk-deep-force (hk-run "main = catch (error \"boom\") (\\(SomeException m) -> return m)")) (list "IO" "boom")) (hk-test "try — success returns Right v" (hk-deep-force (hk-run "main = try (return 42)")) (list "IO" (list "Right" 42))) (hk-test "try — error returns Left (SomeException msg)" (hk-deep-force (hk-run "main = try (error \"oops\")")) (list "IO" (list "Left" (list "SomeException" "oops")))) (hk-test "handle — flip catch — caught error message" (hk-deep-force (hk-run "main = handle (\\(SomeException m) -> return m) (error \"hot\")")) (list "IO" "hot")) (hk-test "throwIO + catch — handler sees the SomeException" (hk-deep-force (hk-run "main = catch (throwIO (SomeException \"bang\")) (\\(SomeException m) -> return m)")) (list "IO" "bang")) (hk-test "throwIO + try — Left side" (hk-deep-force (hk-run "main = try (throwIO (SomeException \"x\"))")) (list "IO" (list "Left" (list "SomeException" "x")))) (hk-test "evaluate — pure value returns IO v" (hk-deep-force (hk-run "main = evaluate (1 + 2 + 3)")) (list "IO" 6)) (hk-test "evaluate — error surfaces as catchable exception" (hk-deep-force (hk-run "main = catch (evaluate (error \"deep\")) (\\(SomeException m) -> return m)")) (list "IO" "deep")) (hk-test "nested catch — inner handler runs first" (hk-deep-force (hk-run "main = catch (catch (error \"inner\") (\\(SomeException m) -> error (m ++ \"-rethrown\"))) (\\(SomeException m) -> return m)")) (list "IO" "inner-rethrown")) (hk-test "catch chain — handler can succeed inside IO" (hk-deep-force (hk-run "main = do { x <- catch (error \"e1\") (\\(SomeException m) -> return 100); return (x + 1) }")) (list "IO" 101)) (hk-test "try then bind on Right" (hk-deep-force (hk-run "branch (Right v) = return (v * 2) branch (Left _) = return 0 main = do { r <- try (return 21); branch r }")) (list "IO" 42)) (hk-test "try then bind on Left" (hk-deep-force (hk-run "branch (Right _) = return \"ok\" branch (Left (SomeException m)) = return m main = do { r <- try (error \"failed\"); branch r }")) (list "IO" "failed")) (hk-test "catch — handler can use closed-over IORef" (hk-deep-force (hk-run "import qualified Data.IORef as IORef main = do r <- IORef.newIORef 0 catch (error \"x\") (\\(SomeException m) -> IORef.writeIORef r 7) v <- IORef.readIORef r return v")) (list "IO" 7))