git.iko.soy/rowtype-yoga/purescript-yoga-om-layer
on main help sign in
Add recovering/repeating combinators to OmLayer
commit192b6c4f739c4b3798bf00d6c6ea522934df2928 authorMark <mark.eibes@gmail.com> dateSat 14 Feb 2026, 00:30 (8 months ago) parentb97f5c6
1 file changed+55−5
test/Test/Main.purs+55−5
test/Test/Main.purs+55−5
@@ -533,7 +533,7 @@ main = launchAff_ $ runSpec [ consoleReporter ] do
533533
534534 retried = layer
535535 # recovering (constantDelay (Milliseconds 0.0) <> limitRetries 5)
536− (\_ -> { dbError: \_ -> pure true })
536+ \_ -> { dbError: \_ -> pure true }
537537
538538 result <- Om.runOm {}
539539 { exception: \_ -> pure { db: "" }, dbError: \_ -> pure { db: "" } }
@@ -552,7 +552,7 @@ main = launchAff_ $ runSpec [ consoleReporter ] do
552552
553553 retried = layer
554554 # recovering (constantDelay (Milliseconds 0.0) <> limitRetries 3)
555− (\_ -> { dbError: \_ -> pure true })
555+ \_ -> { dbError: \_ -> pure true }
556556
557557 _ <- Om.runOm {}
558558 { exception: \_ -> pure { db: "" }
@@ -563,6 +563,56 @@ main = launchAff_ $ runSpec [ consoleReporter ] do
563563 attempts <- liftEffect $ Ref.read attemptsRef
564564 attempts `shouldEqual` 1
565565
566+ it "preserves the error when retries are exhausted" do
567+ let
568+ layer :: OmLayer () (dbError :: String) { db :: String }
569+ layer = makeLayer do
570+ Om.throw { dbError: "connection refused" }
571+
572+ retried = layer
573+ # recovering (constantDelay (Milliseconds 0.0) <> limitRetries 2)
574+ \_ -> { dbError: \_ -> pure true }
575+
576+ result <- Om.runReader {} (runLayer {} retried)
577+ # liftAff
578+ case result of
579+ Left err -> do
580+ let
581+ msg = err # match
582+ { exception: \_ -> "exception"
583+ , dbError: \e -> e
584+ }
585+ msg `shouldEqual` "connection refused"
586+ Right _ -> "should have failed" `shouldEqual` "but succeeded"
587+
588+ it "only retries the specified error in a multi-error layer" do
589+ attemptsRef <- liftEffect $ Ref.new 0
590+ let
591+ layer :: OmLayer () (dbError :: String, cacheError :: String) { db :: String }
592+ layer = makeLayer do
593+ attempts <- Ref.modify (_ + 1) attemptsRef # liftEffect
594+ if attempts <= 2 then Om.throw { dbError: "db down" }
595+ else Om.throw { cacheError: "cache miss" }
596+
597+ retried = layer
598+ # recovering (constantDelay (Milliseconds 0.0) <> limitRetries 5)
599+ \_ -> { dbError: \_ -> pure true }
600+
601+ result <- Om.runReader {} (runLayer {} retried)
602+ # liftAff
603+ case result of
604+ Left err -> do
605+ let
606+ msg = err # match
607+ { exception: \_ -> "exception"
608+ , dbError: \e -> e
609+ , cacheError: \e -> e
610+ }
611+ msg `shouldEqual` "cache miss"
612+ Right _ -> "should have failed" `shouldEqual` "but succeeded"
613+ attempts <- liftEffect $ Ref.read attemptsRef
614+ attempts `shouldEqual` 3
615+
566616 it "uses RetryStatus in the check" do
567617 attemptsRef <- liftEffect $ Ref.new 0
568618 let
@@ -573,7 +623,7 @@ main = launchAff_ $ runSpec [ consoleReporter ] do
573623
574624 retried = layer
575625 # recovering (constantDelay (Milliseconds 0.0) <> limitRetries 10)
576− (\(RetryStatus s) -> { dbError: \_ -> pure (s.iterNumber < 2) })
626+ \(RetryStatus s) -> { dbError: \_ -> pure (s.iterNumber < 2) }
577627
578628 _ <- Om.runOm {}
579629 { exception: \_ -> pure { db: "" }, dbError: \_ -> pure { db: "" } }
@@ -593,7 +643,7 @@ main = launchAff_ $ runSpec [ consoleReporter ] do
593643
594644 repeated = layer
595645 # repeating (constantDelay (Milliseconds 0.0) <> limitRetries 10)
596− (\_ r -> pure (r.count < 5))
646+ \_ r -> pure (r.count < 5)
597647
598648 result <- Om.runOm {}
599649 { exception: \_ -> pure { count: 0 } }
@@ -610,7 +660,7 @@ main = launchAff_ $ runSpec [ consoleReporter ] do
610660
611661 repeated = layer
612662 # repeating (constantDelay (Milliseconds 0.0) <> limitRetries 3)
613− (\_ _ -> pure true)
663+ \_ _ -> pure true
614664
615665 result <- Om.runOm {}
616666 { exception: \_ -> pure { count: 0 } }