Additional method, documentation and test.

This commit is contained in:
Alexander Granin 2020-08-06 18:31:12 +07:00
parent 3e5d7f88b7
commit e83d054ba8
2 changed files with 23 additions and 6 deletions

View File

@ -139,6 +139,13 @@ runDB = evalSqlDB
throwException :: forall a e. Exception e => e -> LangL a throwException :: forall a e. Exception e => e -> LangL a
throwException ex = liftF $ ThrowException ex id throwException ex = liftF $ ThrowException ex id
-- | Catches any type of exceptions and returns as SomeException.
runSafely' :: LangL a -> LangL (Either SomeException a)
runSafely' act = liftF $ RunSafely act id
-- | Catches only a specified type of exceptions or exceptions which are wider.
-- For example, when SomeException is specified, any exceptions will be catched.
-- Otherwise depends on the hierarchy of the exceptions.
runSafely :: Exception e => LangL a -> LangL (Either e a) runSafely :: Exception e => LangL a -> LangL (Either e a)
runSafely act = liftF $ RunSafely act id runSafely act = liftF $ RunSafely act id

View File

@ -55,11 +55,11 @@ spec =
result <- R.runAppL rt app result <- R.runAppL rt app
result `shouldBe` "Some" result `shouldBe` "Some"
it "ThrowException & runSafely, catched second, wider" $ \rt -> do it "ThrowException & runSafely, catched by second, wider" $ \rt -> do
let app = do let app = do
void $ L.scenario void $ L.scenario
$ L.runSafely @SomeException $ L.runSafely @SomeException -- by second
$ L.runSafely @(E.AssertionFailed) $ L.runSafely @(E.AssertionFailed) -- by first
$ L.throwException E.DivideByZero $ L.throwException E.DivideByZero
pure "Some" pure "Some"
result <- R.runAppL rt app result <- R.runAppL rt app
@ -68,14 +68,24 @@ spec =
it "ThrowException & runSafely, not catched any" $ \rt -> do it "ThrowException & runSafely, not catched any" $ \rt -> do
let app = do let app = do
void $ L.scenario void $ L.scenario
$ L.runSafely @(E.AssertionFailed) $ L.runSafely @(E.AssertionFailed) -- second
$ L.runSafely @(E.ArrayException) $ L.runSafely @(E.ArrayException) -- first
$ L.throwException E.DivideByZero $ L.throwException E.DivideByZero
pure "Some" pure "Some"
eRes :: Either SomeException String <- try $ R.runAppL rt app eRes :: Either SomeException String <- try $ R.runAppL rt app
case eRes of case eRes of
Left err -> show err `shouldBe` "divide by zero" Left err -> show err `shouldBe` "divide by zero"
Right res -> fail $ "Unexpected success: " <> res Right res -> fail $ "Unexpected success: " <> res
it "ThrowException & runSafely', catched by second, wider" $ \rt -> do
let app = do
void $ L.scenario
$ L.runSafely' -- second (SomeException)
$ L.runSafely @(E.AssertionFailed) -- first
$ L.throwException E.DivideByZero
pure "Some"
result <- R.runAppL rt app
result `shouldBe` "Some"
it "ThrowException & runSafely, catched after run" $ \rt -> do it "ThrowException & runSafely, catched after run" $ \rt -> do
let (app :: L.AppL (Either E.AssertionFailed Int)) = let (app :: L.AppL (Either E.AssertionFailed Int)) =