Skip to content

Commit

Permalink
WIP: addressing last comments
Browse files Browse the repository at this point in the history
  • Loading branch information
bezirg committed Jan 15, 2021
1 parent fb8abd3 commit 56bacb1
Show file tree
Hide file tree
Showing 20 changed files with 115 additions and 386 deletions.
39 changes: 22 additions & 17 deletions plutus-core/common/ErrorCode.hs
@@ -1,22 +1,26 @@
module ErrorCode
( ErrorCode(..)
, E(..)
( HasErrorCode(..)
, ErrorCode(..)
) where

import Data.Text.Prettyprint.Doc
import Numeric.Natural
import Text.Printf

{- NOTE [Error Codes of plutus errors]
{- Note [Error Codes of plutus errors]
Our goal is to assign a project-wise unique error number (errorCode) to all errors
that might occur during any phase of plutus code --- plutustx th deriving, plugin tx compiling,
pir compiling, plc executing, "offline" runtime plutus code ---, so
as to document and easily identify these plutus errors.
Our goal is to assign a project-wide unique error number (errorCode) to all errors
that might occur during any phase of compilation --- lifting values, compiling Plutus Tx,
compiling PIR, executing PLC, "off-chain" Plutus code ---, so
as to document and easily identify these errors.
We drew inspiration from `rustc` compiler error-codes:
<https://doc.rust-lang.org/nightly/nightly-rustc/rustc_errors/index.html>
Related work on error hierarchy, error annotations for haskell:
<https://gitlab.haskell.org/ghc/ghc/-/wikis/Errors-as-(structured)-values>
<https://github.com/ghc-proposals/ghc-proposals/pull/307>
An errorcode is a positive number (`Natural`) assigned to every possible data-constructor
that represents an exceptional case. This may include both pure error-values raised
by e.g. `ExceptT` but also "impure" ghc-builtin Control.Exception instances.
Expand All @@ -39,13 +43,13 @@ We do not uniquely tag the wrapper-constructors WrapperTC,WrapperParse,WrapperCo
we only tag the "base error constructor" PirCompile:
```
instance ErrorCode PirError where
instance HasErrorCode PirError where
errorCode PirCompile {} = 9997
errorCode (WrapperTC e) = errorCode e
errorCode (WrapperParse e) = errorCode e
```
A Plutus sub-project that wants to throw an error, must depend on this package `plutus-common`.
A Plutus sub-project that wants to throw an error, must depend on this package `plutus-core`.
To aid in defining an instance for a brand-new (uncategorized) error or added error-dataconstructors,
the Plutus developer can make use (but not cabal-depend upon) of the
mega-package plutus-errors to "guess-pick" an error-code that is not currently in use
Expand All @@ -72,14 +76,15 @@ might use sub-groups of error-codes with specific ranges, e.g. (PIR : 0000 - 010
to put into use the "wrapper-constructors" of our error-grouppings.
-}

-- | Assigns an error-code (positive number) to data-constructors (values) of error types.
class ErrorCode a where
errorCode :: a -> E
-- | Assigns an error-code to data-constructors (values) of error types.
-- Note, when implementing this method you're only supposed to look at
-- the outermost constructor (whnf) of the 'a' value to decide for the error-code.
class HasErrorCode a where
errorCode :: a -> ErrorCode

-- a shorthand wrapper to Natural so as to override
-- the pretty instance of Natural, with zero padding
newtype E = E Natural
-- | A wrapper to Natural so as to override the pretty instance of Natural with zero padding
newtype ErrorCode = ErrorCode Natural
deriving newtype (Eq, Ord)

instance Pretty E where
pretty (E n) = pretty (printf "E%03d" n :: String)
instance Pretty ErrorCode where
pretty (ErrorCode n) = pretty (printf "E%03d" n :: String)
10 changes: 5 additions & 5 deletions plutus-core/plutus-ir/Language/PlutusIR/Error.hs
Expand Up @@ -38,8 +38,8 @@ data TypeErrorExt uni ann =
deriving (Show, Eq, Generic, NFData)
makeClassyPrisms ''TypeErrorExt

instance ErrorCode (TypeErrorExt _a _b) where
errorCode MalformedDataConstrResType {} = E 1
instance HasErrorCode (TypeErrorExt _a _b) where
errorCode MalformedDataConstrResType {} = ErrorCode 1

data Error uni fun a = CompilationError a T.Text -- ^ A generic compilation error.
| UnsupportedError a T.Text -- ^ An error relating specifically to an unsupported feature.
Expand All @@ -49,9 +49,9 @@ data Error uni fun a = CompilationError a T.Text -- ^ A generic compilation erro
deriving (Typeable)
makeClassyPrisms ''Error

instance ErrorCode (Error _a _b _c) where
errorCode UnsupportedError {} = E 3
errorCode CompilationError {} = E 2
instance HasErrorCode (Error _a _b _c) where
errorCode UnsupportedError {} = ErrorCode 3
errorCode CompilationError {} = ErrorCode 2
errorCode (PIRTypeError e) = errorCode e
errorCode (PLCTypeError e) = errorCode e
errorCode (PLCError e) = errorCode e
Expand Down
6 changes: 3 additions & 3 deletions plutus-core/plutus-ir/Language/PlutusIR/Parser.hs
Expand Up @@ -53,9 +53,9 @@ data ParseError = UnknownBuiltinType T.Text
| InvalidConstant T.Text T.Text
deriving (Eq, Ord, Show)

instance ErrorCode ParseError where
errorCode UnknownBuiltinType {} = E 5
errorCode InvalidConstant {} = E 4
instance HasErrorCode ParseError where
errorCode UnknownBuiltinType {} = ErrorCode 5
errorCode InvalidConstant {} = ErrorCode 4

type Error = Parsec.ParseError Char ParseError

Expand Down
6 changes: 3 additions & 3 deletions plutus-core/src/Language/PlutusCore/DeBruijn/Internal.hs
Expand Up @@ -165,9 +165,9 @@ data FreeVariableError
deriving (Show, Typeable, Eq, Ord)
instance Exception FreeVariableError

instance ErrorCode FreeVariableError where
errorCode FreeIndex {} = E 23
errorCode FreeUnique {} = E 22
instance HasErrorCode FreeVariableError where
errorCode FreeIndex {} = ErrorCode 23
errorCode FreeUnique {} = ErrorCode 22

-- | Get the 'Index' corresponding to a given 'Unique'.
getIndex :: (MonadReader Levels m, MonadError FreeVariableError m) => Unique -> m Index
Expand Down
48 changes: 24 additions & 24 deletions plutus-core/src/Language/PlutusCore/Error.hs
Expand Up @@ -183,30 +183,30 @@ instance (GShow uni, Closed uni, uni `Everywhere` PrettyConst, Pretty fun, Prett
prettyBy config (TypeErrorE e) = prettyBy config e
prettyBy config (NormCheckErrorE e) = prettyBy config e

instance ErrorCode (ParseError _a) where
errorCode InvalidBuiltinConstant {} = E 10
errorCode UnknownBuiltinFunction {} = E 9
errorCode UnknownBuiltinType {} = E 8
errorCode Unexpected {} = E 7
errorCode LexErr {} = E 6

instance ErrorCode (UniqueError _a) where
errorCode FreeVariable {} = E 21
errorCode IncoherentUsage {} = E 12
errorCode MultiplyDefined {} = E 11

instance ErrorCode (NormCheckError _a _b _c _d _e) where
errorCode BadTerm {} = E 14
errorCode BadType {} = E 13

instance ErrorCode (TypeError _a _b _c _d) where
errorCode FreeVariableE {} = E 20
errorCode FreeTypeVariableE {} = E 19
errorCode TypeMismatch {} = E 16
errorCode KindMismatch {} = E 15
errorCode UnknownBuiltinFunctionE {} = E 18

instance ErrorCode (Error _a _b _c) where
instance HasErrorCode (ParseError _a) where
errorCode InvalidBuiltinConstant {} = ErrorCode 10
errorCode UnknownBuiltinFunction {} = ErrorCode 9
errorCode UnknownBuiltinType {} = ErrorCode 8
errorCode Unexpected {} = ErrorCode 7
errorCode LexErr {} = ErrorCode 6

instance HasErrorCode (UniqueError _a) where
errorCode FreeVariable {} = ErrorCode 21
errorCode IncoherentUsage {} = ErrorCode 12
errorCode MultiplyDefined {} = ErrorCode 11

instance HasErrorCode (NormCheckError _a _b _c _d _e) where
errorCode BadTerm {} = ErrorCode 14
errorCode BadType {} = ErrorCode 13

instance HasErrorCode (TypeError _a _b _c _d) where
errorCode FreeVariableE {} = ErrorCode 20
errorCode FreeTypeVariableE {} = ErrorCode 19
errorCode TypeMismatch {} = ErrorCode 16
errorCode KindMismatch {} = ErrorCode 15
errorCode UnknownBuiltinFunctionE {} = ErrorCode 18

instance HasErrorCode (Error _a _b _c) where
errorCode (ParseErrorE e) = errorCode e
errorCode (UniqueCoherencyErrorE e) = errorCode e
errorCode (TypeErrorE e) = errorCode e
Expand Down
6 changes: 3 additions & 3 deletions plutus-core/src/Language/PlutusCore/Evaluation/Machine/Cek.hs
Expand Up @@ -122,9 +122,9 @@ data CekUserError
| CekEvaluationFailure -- ^ Error has been called or a builtin application has failed
deriving (Show, Eq)

instance ErrorCode CekUserError where
errorCode CekEvaluationFailure {} = E 37
errorCode CekOutOfExError {} = E 36
instance HasErrorCode CekUserError where
errorCode CekEvaluationFailure {} = ErrorCode 37
errorCode CekOutOfExError {} = ErrorCode 36

{- Note [Being generic over @term@ in 'CekM']
We have a @term@-generic version of 'CekM' called 'CekCarryingM', which itself requires a
Expand Down
32 changes: 16 additions & 16 deletions plutus-core/src/Language/PlutusCore/Evaluation/Machine/Exception.hs
Expand Up @@ -237,29 +237,29 @@ instance (PrettyPlc term, PrettyPlc err, Typeable term, Typeable err) =>
Exception (ErrorWithCause err term)


instance ErrorCode UnliftingError where
errorCode UnliftingErrorE {} = E 30
instance HasErrorCode UnliftingError where
errorCode UnliftingErrorE {} = ErrorCode 30

instance ErrorCode (ConstAppError _a _b) where
errorCode TooManyArgumentsConstAppError {} = E 29
errorCode TooFewArgumentsConstAppError {} = E 28
instance HasErrorCode (ConstAppError _a _b) where
errorCode TooManyArgumentsConstAppError {} = ErrorCode 29
errorCode TooFewArgumentsConstAppError {} = ErrorCode 28
errorCode (UnliftingConstAppError e) = errorCode e

instance ErrorCode (MachineError err _a) where
errorCode EmptyBuiltinArityMachineError {} = E 34
errorCode UnexpectedBuiltinTermArgumentMachineError {} = E 33
errorCode BuiltinTermArgumentExpectedMachineError {} = E 32
errorCode OpenTermEvaluatedMachineError {} = E 27
errorCode NonFunctionalApplicationMachineError {} = E 26
errorCode NonWrapUnwrappedMachineError {} = E 25
errorCode NonPolymorphicInstantiationMachineError {} = E 24
instance HasErrorCode (MachineError err _a) where
errorCode EmptyBuiltinArityMachineError {} = ErrorCode 34
errorCode UnexpectedBuiltinTermArgumentMachineError {} = ErrorCode 33
errorCode BuiltinTermArgumentExpectedMachineError {} = ErrorCode 32
errorCode OpenTermEvaluatedMachineError {} = ErrorCode 27
errorCode NonFunctionalApplicationMachineError {} = ErrorCode 26
errorCode NonWrapUnwrappedMachineError {} = ErrorCode 25
errorCode NonPolymorphicInstantiationMachineError {} = ErrorCode 24
errorCode (ConstAppMachineError e) = errorCode e
errorCode UnknownBuiltin {} = E 17
errorCode UnknownBuiltin {} = ErrorCode 17

instance (ErrorCode user, ErrorCode internal) => ErrorCode (EvaluationError user internal) where
instance (HasErrorCode user, HasErrorCode internal) => HasErrorCode (EvaluationError user internal) where
errorCode (InternalEvaluationError e) = errorCode e
errorCode (UserEvaluationError e) = errorCode e


instance ErrorCode err => ErrorCode (ErrorWithCause err t) where
instance HasErrorCode err => HasErrorCode (ErrorWithCause err t) where
errorCode (ErrorWithCause e _) = errorCode e
Expand Up @@ -118,9 +118,9 @@ data CekUserError
deriving (Show, Eq)

-- FIXME: should this be the same errorcodes as the typed-plutus-core.CekUserError original datatype?
instance ErrorCode CekUserError where
errorCode CekEvaluationFailure {} = E 39
errorCode CekOutOfExError {} = E 38
instance HasErrorCode CekUserError where
errorCode CekEvaluationFailure {} = ErrorCode 39
errorCode CekOutOfExError {} = ErrorCode 38

{- Note [Being generic over @term@ in 'CekM']
We have a @term@-generic version of 'CekM' called 'CekCarryingM', which itself requires a
Expand Down
2 changes: 1 addition & 1 deletion plutus-errors/README.md
Expand Up @@ -4,7 +4,7 @@ The `ErrorCode` typeclass under `plutus-core/common/ErrorCode.hs`
assigns a positive number (`Natural`) to every error thrown by Plutus code.
This package provides:

1. A Haddock catalogue of all errors (in-use or obsolete) and their codes `src/Docs.hs`.
1. A Haddock catalogue of all errors (in-use or obsolete) and their codes `src/Errors/Docs.hs`.
2. A check for duplicates among error codes (implicitly achieved by haddock).
3. An executable `plutus-errors-next` to be used by Plutus developers to fetch a currently-unused error code (number).
4. An executable `plutus-errors-bootstrap` to initialize the codebase with automatically-generated `ErrorCode` instances.
Expand Down

0 comments on commit 56bacb1

Please sign in to comment.