Skip to content

Commit d153f06

Browse files
committed
refactor(cabal-install, cabal-install-solver): avoid using "error" in validateSolverResult
- Add a `step` helper and a `MonadFail` instance to `Progress` - Refactor `validateSolverResult` to integrate into the `Progress` monad chain using `fail` instead of `error`, giving structured failure instead of an uncatchable exception
1 parent ec8052b commit d153f06

3 files changed

Lines changed: 31 additions & 25 deletions

File tree

cabal-install-solver/src/Distribution/Solver/Types/Progress.hs

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
1+
{-# LANGUAGE FlexibleInstances #-}
12
module Distribution.Solver.Types.Progress
23
( Progress(..)
34
, foldProgress
5+
, step
6+
, fail
47
) where
58

69
import Prelude ()
7-
import Distribution.Solver.Compat.Prelude hiding (fail)
10+
import Distribution.Solver.Compat.Prelude
811

912
-- | A type to represent the unfolding of an expensive long running
1013
-- calculation that may fail. We may get intermediate steps before the final
@@ -22,6 +25,9 @@ instance Functor (Progress step fail) where
2225
fmap _ (Fail x) = Fail x
2326
fmap f (Done r) = Done (f r)
2427

28+
step :: step -> Progress step fail ()
29+
step s = Step s (Done ())
30+
2531
-- | Consume a 'Progress' calculation. Much like 'foldr' for lists but with two
2632
-- base cases, one for a final result and one for failure.
2733
--
@@ -31,15 +37,18 @@ instance Functor (Progress step fail) where
3137
--
3238
foldProgress :: (step -> a -> a) -> (fail -> a) -> (done -> a)
3339
-> Progress step fail done -> a
34-
foldProgress step fail done = fold
35-
where fold (Step s p) = step s (fold p)
36-
fold (Fail f) = fail f
37-
fold (Done r) = done r
40+
foldProgress step' fail' done' = fold
41+
where fold (Step s p) = step' s (fold p)
42+
fold (Fail f) = fail' f
43+
fold (Done r) = done' r
3844

3945
instance Monad (Progress step fail) where
4046
return = pure
4147
p >>= f = foldProgress Step Fail f p
4248

49+
instance MonadFail (Progress step String) where
50+
fail = Fail
51+
4352
instance Applicative (Progress step fail) where
4453
pure a = Done a
4554
p <*> x = foldProgress Step Fail (`fmap` x) p

cabal-install/src/Distribution/Client/Dependency.hs

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,3 @@
1-
-----------------------------------------------------------------------------
2-
3-
-----------------------------------------------------------------------------
4-
51
-- |
62
-- Module : Distribution.Client.Dependency
73
-- Copyright : (c) David Himmelstrup 2005,
@@ -805,9 +801,9 @@ resolveDependencies
805801
-> Maybe PkgConfigDb
806802
-> DepResolverParams
807803
-> Progress String String SolverInstallPlan
808-
resolveDependencies platform comp pkgConfigDB params =
809-
Step (showDepResolverParams finalparams) $
810-
fmap (validateSolverResult platform comp indGoals) $
804+
resolveDependencies platform comp pkgConfigDB params = do
805+
step (showDepResolverParams finalparams)
806+
pkgs <-
811807
formatProgress $
812808
runSolver
813809
( SolverConfig
@@ -835,6 +831,7 @@ resolveDependencies platform comp pkgConfigDB params =
835831
preferences
836832
constraints
837833
targets
834+
validateSolverResult platform comp indGoals pkgs
838835
where
839836
finalparams@( DepResolverParams
840837
targets
@@ -935,13 +932,13 @@ validateSolverResult
935932
-> CompilerInfo
936933
-> IndependentGoals
937934
-> [ResolverPackage UnresolvedPkgLoc]
938-
-> SolverInstallPlan
935+
-> Progress String String SolverInstallPlan
939936
validateSolverResult platform comp indepGoals pkgs =
940937
case planPackagesProblems platform comp pkgs of
941938
[] -> case SolverInstallPlan.new indepGoals graph of
942-
Right plan -> plan
943-
Left problems -> error (formatPlanProblems problems)
944-
problems -> error (formatPkgProblems problems)
939+
Right plan -> return plan
940+
Left problems -> fail (formatPlanProblems problems)
941+
problems -> fail (formatPkgProblems problems)
945942
where
946943
graph :: Graph.Graph (ResolverPackage UnresolvedPkgLoc)
947944
graph = Graph.fromDistinctList pkgs

cabal-install/tests/UnitTests/Distribution/Solver/Modular/RetryLog.hs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -35,15 +35,15 @@ tests =
3535
\p (Blind f) ->
3636
toProgress (retry (fromProgress p) (fromProgress . f))
3737
=== (foldProgress Step f Done (p :: Log Int) :: Log Int)
38-
, testProperty "failWith" $ \step failure ->
39-
toProgress (failWith step failure)
40-
=== (Step step (Fail failure) :: Log Int)
41-
, testProperty "succeedWith" $ \step success ->
42-
toProgress (succeedWith step success)
43-
=== (Step step (Done success) :: Log Int)
44-
, testProperty "continueWith" $ \step p ->
45-
toProgress (continueWith step (fromProgress p))
46-
=== (Step step p :: Log Int)
38+
, testProperty "failWith" $ \step' failure ->
39+
toProgress (failWith step' failure)
40+
=== (Step step' (Fail failure) :: Log Int)
41+
, testProperty "succeedWith" $ \step' success ->
42+
toProgress (succeedWith step' success)
43+
=== (Step step' (Done success) :: Log Int)
44+
, testProperty "continueWith" $ \step' p ->
45+
toProgress (continueWith step' (fromProgress p))
46+
=== (Step step' p :: Log Int)
4747
, testCase "tryWith with failure" $
4848
let failure = Fail "Error"
4949
s = Step Success

0 commit comments

Comments
 (0)