lorentz-0.15.1: EDSL for the Michelson Language
Safe HaskellSafe-Inferred
LanguageHaskell2010

Lorentz.Errors.Numeric.Contract

Description

By default we represent error tags using strings. This module makes it possible to use numbers instead. It introduces new [error format].

There are two possible ways to use it: 1. If you have just one Lorentz instruction (potentially a big one), just use useNumericErrors function. It will change error representation there and return a map that can be used to interpret new error codes. 2. If your contract consists of multiple parts, start with gathering all error tags (gatherErrorTags). Then build ErrorTagMap using addNewErrorTags. Pass empty map if you are building from scratch (you can use buildErrorTagMap shortcut) or an existing map if you have one (e. g. you are upgrading a contract).

Synopsis

Documentation

type ErrorTagMap = Bimap Natural MText Source #

This is a bidirectional map with correspondence between numeric and textual error tags.

type ErrorTagExclusions = HashSet MText Source #

Tags excluded from map.

gatherErrorTags :: (inp :-> out) -> HashSet MText Source #

Find all textual error tags that are used in typical FAILWITH patterns within given instruction. Map them to natural numbers.

addNewErrorTags :: ErrorTagMap -> HashSet MText -> ErrorTagMap Source #

Add more error tags to an existing ErrorTagMap. It is useful when your contract consists of multiple parts (e. g. in case of contract upgrade), you have existing map for some part and want to add tags from another part to it. You can pass empty map as existing one if you just want to build ErrorTagMap from a set of textual tags. See buildErrorTagMap.

buildErrorTagMap :: HashSet MText -> ErrorTagMap Source #

Build ErrorTagMap from a set of textual tags.

excludeErrorTags :: HasCallStack => ErrorTagExclusions -> ErrorTagMap -> ErrorTagMap Source #

Remove some error tags from map. This way you say to remain these string tags intact, while others will be converted to numbers when this map is applied.

Note that later you have to apply this map using applyErrorTagMapWithExclusions, otherwise an error would be raised.

applyErrorTagMap :: HasCallStack => ErrorTagMap -> (inp :-> out) -> inp :-> out Source #

For each typical FAILWITH that uses a string to represent error tag this function changes error tag to be a number using the supplied conversion map. It assumes that supplied map contains all such strings (and will error out if it does not). It will always be the case if you gather all error tags using gatherErrorTags and build ErrorTagMap from them using addNewErrorTags.

applyErrorTagMapWithExclusions :: HasCallStack => ErrorTagMap -> ErrorTagExclusions -> (inp :-> out) -> inp :-> out Source #

Similar to applyErrorTagMap, but for case when you have excluded some tags from map via excludeErrorTags. Needed, because both excludeErrorTags and this function do not tolerate unknown errors in contract code (for your safety).

useNumericErrors :: HasCallStack => (inp :-> out) -> (inp :-> out, ErrorTagMap) Source #

This function implements the simplest scenario of using this module's functionality: 1. Gather all error tags from a single instruction. 2. Turn them into error conversion map. 3. Apply this conversion.

errorFromValNumeric :: (SingI t, IsError e) => ErrorTagMap -> Value t -> Either Text e Source #

If you apply numeric error representation in your contract, errorFromVal will stop working because it doesn't know about this transformation. This function takes this transformation into account. If a number is used as a tag, but it is not found in the passed map, we conservatively preserve that number (because this whole approach is rather a heuristic).

errorToValNumeric :: IsError e => ErrorTagMap -> e -> (forall t. ConstantScope t => Value t -> r) -> r Source #

If you apply numeric error representation in your contract, errorToVal will stop working because it doesn't know about this transformation. This function takes this transformation into account. If a string is used as a tag, but it is not found in the passed map, we conservatively preserve that string (because this whole approach is rather a heuristic).