Skip to content

Commit

Permalink
Core: ADT-ize all errors
Browse files Browse the repository at this point in the history
  • Loading branch information
jmcardon committed Jun 4, 2024
1 parent 6168b06 commit 069021c
Show file tree
Hide file tree
Showing 32 changed files with 920 additions and 624 deletions.
2 changes: 1 addition & 1 deletion gasmodel/Pact/Core/GasModel/InterpreterGas.hs
Original file line number Diff line number Diff line change
Expand Up @@ -370,7 +370,7 @@ gasMtWithHandlerError pdb =
let es = defaultGasEvalState
ps = _eeDefPactStep ee
frame = Mt
value = VError "foo" ()
value = VError [] (UserEnforceError "foo") ()
env = CEKEnv { _cePactDb=pdb
, _ceLocal=mempty
, _ceInCap=False
Expand Down
2 changes: 1 addition & 1 deletion pact-lsp/Pact/Core/LanguageServer.hs
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ sendDiagnostics nuri mv content = liftIO runPact >>= \case
PEParseError{} -> "Parse"
PEDesugarError{} -> "Desugar"
PEExecutionError{} -> "Execution"
PERecoverableError{} -> "Execution"
PEUserRecoverableError{} -> "Execution"

spanInfoToRange :: SpanInfo -> Range
spanInfoToRange (SpanInfo sl sc el ec) = mkRange
Expand Down
17 changes: 10 additions & 7 deletions pact-tests/Pact/Core/Test/StaticErrorTests.hs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ isDesugarError p s = isJust $ preview (_PEDesugarError . _1 . p) s
isExecutionError :: Prism' EvalError a -> PactErrorI -> Bool
isExecutionError p s = isJust $ preview (_PEExecutionError . _1 . p) s

isUserRecoverableError :: Prism' UserRecoverableError a -> PactErrorI -> Bool
isUserRecoverableError p s = isJust $ preview (_PEUserRecoverableError . _1 . p) s

runStaticTest :: String -> Text -> (PactErrorI -> Bool) -> Assertion
runStaticTest label src predicate = do
gasLog <- newIORef Nothing
Expand Down Expand Up @@ -627,7 +630,7 @@ executionTests =
, ("get_module_unknown", isExecutionError _ModuleDoesNotExist, [text|
(describe-module 'nonexistent)
|])
, ("reexposed_module_missing_name", isExecutionError _NameNotInScope, [text|
, ("reexposed_module_missing_name", isExecutionError _ModuleMemberDoesNotExist, [text|
(module m g
(defcap g () true)

Expand All @@ -650,15 +653,15 @@ executionTests =
, ("module_gov_keyset_nonexistent", isExecutionError _NoSuchKeySet, [text|
(module m 'nonexistent (defun f () true))
|])
, ("module_gov_keyset_different", isExecutionError _EvalError, [text|
, ("module_gov_keyset_different", isUserRecoverableError _KeysetPredicateFailure, [text|
(env-data {"ks":["jose"]})
(define-keyset 'somekeyset (read-keyset 'ks))
(module m 'somekeyset (defun f () 1))
|])
, ("module_gov_keyset_empty", isExecutionError _ModuleGovernanceFailure, [text|
, ("module_gov_keyset_empty", isExecutionError _InvalidKeysetNameFormat, [text|
(module m "" (defun f () true))
|])
, ("module_gov_keyset_not_in_sigs", isExecutionError _EvalError, [text|
, ("module_gov_keyset_not_in_sigs", isUserRecoverableError _KeysetPredicateFailure, [text|
(env-data { "kall": ["a" "b" "c"], "kadmin": ["admin"] })
(define-keyset 'kall)
(define-keyset 'kadmin)
Expand All @@ -678,7 +681,7 @@ executionTests =
|])

-- CEK errors
, ("modref_no_ns", isExecutionError _ModRefNotRefined, [text|
, ("modref_no_ns", isExecutionError _ModRefImplementsNoInterfaces, [text|
(module m g (defcap g () true))
m
|])
Expand Down Expand Up @@ -1080,8 +1083,8 @@ builtinTests =
, ("at_oob_bound", isExecutionError _ArrayOutOfBoundsException, "(at 3 [1 2 3])")
, ("at_oob_smaller", isExecutionError _ArrayOutOfBoundsException, "(at -1 [1 2 3])")
, ("at_oob_empty", isExecutionError _ArrayOutOfBoundsException, "(at 0 [])")
, ("at_key_missing", isExecutionError _EvalError, "(at 'bar { 'foo: 1 })")
, ("yield_outside", isExecutionError _YieldOutsiteDefPact, "(yield {})")
, ("at_key_missing", isExecutionError _ObjectIsMissingField, "(at 'bar { 'foo: 1 })")
, ("yield_outside", isExecutionError _YieldOutsideDefPact, "(yield {})")
, ("resume_no_defpact", isExecutionError _NoActiveDefPactExec, "(resume { 'field := binder } binder)")
, ("resume_no_yield", isExecutionError _NoYieldInDefPactStep, [text|
(module m g (defcap g () true)
Expand Down
1 change: 1 addition & 0 deletions pact-tests/Pact/Core/Test/TestPrisms.hs
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@ makePrisms ''LexerError
makePrisms ''ParseError
makePrisms ''DesugarError
makePrisms ''EvalError
makePrisms ''UserRecoverableError
makePrisms ''PactError
4 changes: 2 additions & 2 deletions pact-tests/legacy-serial-tests/coin-v5/coin-v5.repl
Original file line number Diff line number Diff line change
Expand Up @@ -421,7 +421,7 @@
(transfer 'emily 'doug 1.0))

(expect-failure "No account for will"
"no such read object"
"No value found in table coin:coin-table for key: will"
(get-balance 'will))

(test-capability (TRANSFER 'doug 'will 1.0))
Expand Down Expand Up @@ -485,7 +485,7 @@
(env-data { "miner2": ["miner2"] })

(expect-failure "no account for miner2"
"no such read object"
"No value found in table coin:coin-table for key: miner2"
(get-balance 'miner2))

(test-capability (COINBASE))
Expand Down
6 changes: 3 additions & 3 deletions pact-tests/pact-tests/caps.repl
Original file line number Diff line number Diff line change
Expand Up @@ -814,7 +814,7 @@

(expect-failure
"cap guard fails on wrong cap"
"Capability guard enforce failure cap not in scope"
"Capability not acquired"
(test-cap-guard "A" "B"))

(env-hash (hash 1))
Expand All @@ -831,7 +831,7 @@
(cg-pact 'k2 'k2 "D" "E")
(expect-failure
"cap pact guard fails on wrong cap"
"Capability guard enforce failure cap not in scope"
"Capability not acquired"
(continue-pact 1))

(pact-state true)
Expand Down Expand Up @@ -914,7 +914,7 @@

(expect-failure
"out-of-band call fails"
"Capability guard enforce failure cap not in scope"
"Capability not acquired"
(call-op1 "hello" 2))
(expect
"normal case succeeds for both callees post-fork"
Expand Down
4 changes: 2 additions & 2 deletions pact-tests/pact-tests/coin-v1.repl
Original file line number Diff line number Diff line change
Expand Up @@ -422,7 +422,7 @@
(transfer 'emily 'doug 1.0))

(expect-failure "No account for will"
"no such read object"
"No value found in table coin:coin-table for key: will"
(get-balance 'will))

(test-capability (TRANSFER 'doug 'will 1.0))
Expand Down Expand Up @@ -484,7 +484,7 @@
(env-data { "miner2": ["miner2"] })

(expect-failure "no account for miner2"
"no such read object"
"No value found in table coin:coin-table for key: miner2"
(get-balance 'miner2))

(coinbase 'miner2 (read-keyset 'miner2) 1.0)
Expand Down
4 changes: 2 additions & 2 deletions pact-tests/pact-tests/coin-v5.repl
Original file line number Diff line number Diff line change
Expand Up @@ -435,7 +435,7 @@
(transfer 'emily 'doug 1.0))

(expect-failure "No account for will"
"no such read object"
"No value found in table coin:coin-table for key: will"
(get-balance 'will))

(test-capability (TRANSFER 'doug 'will 1.0))
Expand Down Expand Up @@ -499,7 +499,7 @@
(env-data { "miner2": ["miner2"] })

(expect-failure "no account for miner2"
"no such read object"
"No value found in table coin:coin-table for key: miner2"
(get-balance 'miner2))

(test-capability (COINBASE))
Expand Down
3 changes: 3 additions & 0 deletions pact/Pact/Core/Capabilities.hs
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,9 @@ data Signer name v = Signer
-- ^ clist for designating signature to specific caps
} deriving (Eq, Ord, Show, Generic)

instance (Pretty name, Pretty v) => Pretty (CapToken name v) where
pretty (CapToken qn args) =
parens (pretty qn <> if null args then mempty else hsep (pretty <$> args))

instance (NFData name, NFData v) => NFData (Signer name v)
instance (NFData name, NFData e) => NFData (CapForm name e)
Expand Down
1 change: 0 additions & 1 deletion pact/Pact/Core/Compile.hs
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,6 @@ enforceNamespaceInstall info interpreter =
useEvalState (esLoaded . loNamespace) >>= \case
Just ns ->
void $ interpretGuard interpreter info (_nsUser ns)
-- Eval.interpretGuard info bEnv (_nsUser ns)
Nothing ->
enforceRootNamespacePolicy
where
Expand Down
5 changes: 5 additions & 0 deletions pact/Pact/Core/DefPacts/Types.hs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import Pact.Core.PactValue
import Pact.Core.Names
import Pact.Core.Hash
import Pact.Core.ChainData
import Pact.Core.Pretty

data DefPactContinuation name v
= DefPactContinuation
Expand Down Expand Up @@ -79,3 +80,7 @@ instance NFData Yield
instance NFData DefPactStep
instance (NFData name, NFData v) => NFData (DefPactContinuation name v)
instance NFData DefPactExec

instance (Pretty name, Pretty v) => Pretty (DefPactContinuation name v) where
pretty (DefPactContinuation n v) =
parens (pretty n <+> if null v then mempty else space <> hsep (pretty <$> v))
27 changes: 17 additions & 10 deletions pact/Pact/Core/Environment/Utils.hs
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,15 @@ module Pact.Core.Environment.Utils
, lookupModule
, lookupModuleData
, throwExecutionError
, throwExecutionError'
, throwRecoverableError
, toFqDep
, mangleNamespace
, getAllStackCaps
, checkSigCaps
, allModuleExports
, liftDbFunction
, throwUserRecoverableError
, throwUserRecoverableError'
, throwNativeExecutionError
) where

import Control.Lens
Expand All @@ -36,7 +37,6 @@ import Control.Monad.Except
import Control.Exception
import Control.Monad.IO.Class(MonadIO(..))
import Data.Text(Text)
import Data.Default
import Data.Maybe(mapMaybe)
import qualified Data.Map.Strict as M
import qualified Data.Set as S
Expand All @@ -51,6 +51,7 @@ import Pact.Core.Namespace
import Pact.Core.Guards
import Pact.Core.Capabilities
import Pact.Core.PactValue
import Pact.Core.Builtin

viewEvalEnv :: (MonadEvalEnv b i m) => Lens' (EvalEnv b i) s -> m s
viewEvalEnv l = view l <$> readEnv
Expand Down Expand Up @@ -100,16 +101,22 @@ liftDbFunction info action = do
Left dbopErr -> throwExecutionError info (DbOpFailure dbopErr)
Right e -> pure e

throwUserRecoverableError :: (MonadError (PactError info) m, MonadEvalState b info m) => info -> UserRecoverableError -> m a
throwUserRecoverableError i err = do
st <- useEvalState esStack
throwError (PEUserRecoverableError err st i)

throwUserRecoverableError' :: MonadError (PactError info) m => info -> [StackFrame info] -> UserRecoverableError -> m a
throwUserRecoverableError' info stack err = throwError (PEUserRecoverableError err stack info)

throwExecutionError :: (MonadEvalState b i m, MonadError (PactError i) m) => i -> EvalError -> m a
throwExecutionError i e = do
st <- useEvalState esStack
throwError (PEExecutionError e st i)

throwRecoverableError :: MonadEval b i m => i -> Text -> m a
throwRecoverableError i e = throwError (PERecoverableError (RecoverableError e) i)

throwExecutionError' :: (MonadEvalState b i m, MonadError (PactError i) m, Default i) => EvalError -> m a
throwExecutionError' = throwExecutionError def
throwNativeExecutionError :: (MonadEvalState b i m, MonadError (PactError i) m, IsBuiltin b) => i -> b -> Text -> m a
throwNativeExecutionError info b msg =
throwExecutionError info (NativeExecutionError (builtinName b) msg)

-- | lookupModuleData for only modules
lookupModule :: (MonadEval b i m) => i -> PactDb b i -> ModuleName -> m (Maybe (EvalModule b i))
Expand Down Expand Up @@ -170,7 +177,7 @@ getModuleMember info pdb (QualifiedName qn mn) = do
Just d -> pure d
Nothing -> do
let fqn = FullyQualifiedName mn qn (_mHash md)
throwExecutionError info (NameNotInScope fqn)
throwExecutionError info (ModuleMemberDoesNotExist fqn)

getModuleMemberWithHash :: (MonadEval b i m) => i -> PactDb b i -> QualifiedName -> m (EvalDef b i, ModuleHash)
getModuleMemberWithHash info pdb (QualifiedName qn mn) = do
Expand All @@ -179,7 +186,7 @@ getModuleMemberWithHash info pdb (QualifiedName qn mn) = do
Just d -> pure (d, _mHash md)
Nothing -> do
let fqn = FullyQualifiedName mn qn (_mHash md)
throwExecutionError info (NameNotInScope fqn)
throwExecutionError info (ModuleMemberDoesNotExist fqn)


mangleNamespace :: (MonadEvalState b i m) => ModuleName -> m ModuleName
Expand Down
Loading

0 comments on commit 069021c

Please sign in to comment.