packages/codec/lib/format/errors.ts
/**
* Contains the types for error and `ErrorResult` objects.
* @category Main Format
*
* @packageDocumentation
*/
import debugModule from "debug";
const debug = debugModule("codec:format:errors");
//error counterpart to values.ts
//Note: Many of the errors defined here deliberately *don't* extend Error.
//This is because they're not for throwing. If you want to throw one,
//wrap it in a DecodingError.
import type BN from "bn.js";
import type * as Types from "./types";
import type * as Ast from "@truffle/codec/ast/types";
import type * as Storage from "@truffle/codec/storage/types";
import type { PaddingType } from "@truffle/codec/common";
import type {
FunctionInternalRawInfo,
FunctionInternalRawInfoPcPair
} from "./internal";
/*
* SECTION 1: Generic types for values in general (including errors).
*/
/**
* A result which is an error rather than a value
*
* @Category General categories
*/
export type ErrorResult =
| ElementaryErrorResult
| ArrayErrorResult
| MappingErrorResult
| StructErrorResult
| MagicErrorResult
| TypeErrorResult
| TupleErrorResult
| FunctionExternalErrorResult
| FunctionInternalErrorResult
| OptionsErrorResult;
/**
* An error result for an ABI type
*
* @Category General categories
*/
export type AbiErrorResult =
| UintErrorResult
| IntErrorResult
| BoolErrorResult
| BytesErrorResult
| AddressErrorResult
| FixedErrorResult
| UfixedErrorResult
| StringErrorResult
| ArrayErrorResult
| FunctionExternalErrorResult
| TupleErrorResult;
/**
* One of the underlying errors contained in an [[ErrorResult]]
*
* @Category General categories
*/
export type DecoderError =
| GenericError
| UintError
| IntError
| BoolError
| BytesStaticError
| BytesDynamicError
| AddressError
| StringError
| FixedError
| UfixedError
| ArrayError
| MappingError
| StructError
| MagicError
| TypeErrorUnion
| TupleError
| EnumError
| UserDefinedValueTypeError
| ContractError
| FunctionExternalError
| FunctionInternalError
| InternalUseError;
/*
* SECTION 2: Built-in elementary types
*/
/**
* An error result for an elementary value
*
* @Category Elementary types
*/
export type ElementaryErrorResult =
| UintErrorResult
| IntErrorResult
| BoolErrorResult
| BytesErrorResult
| AddressErrorResult
| StringErrorResult
| FixedErrorResult
| UfixedErrorResult
| EnumErrorResult
| UserDefinedValueTypeErrorResult
| ContractErrorResult;
/**
* An error result for a built-in value type
*
* @Category Elementary types
*/
export type BuiltInValueErrorResult =
| UintErrorResult
| IntErrorResult
| BoolErrorResult
| BytesStaticErrorResult
| AddressErrorResult
| FixedErrorResult
| UfixedErrorResult;
/**
* An error result for a bytestring
*
* @Category Elementary types
*/
export type BytesErrorResult = BytesStaticErrorResult | BytesDynamicErrorResult;
/**
* An error result for an unsigned integer
*
* @Category Elementary types
*/
export interface UintErrorResult {
type: Types.UintType;
kind: "error";
error: GenericError | UintError;
}
/**
* A uint-specific error
*
* @Category Elementary types
*/
export type UintError = UintPaddingError;
/**
* A padding error for an unsigned integer (note padding is not always checked)
*
* @Category Elementary types
*/
export interface UintPaddingError {
/**
* hex string
*/
raw: string;
kind: "UintPaddingError";
paddingType: PaddingType;
}
/**
* An error result for a signed integer
*
* @Category Elementary types
*/
export interface IntErrorResult {
type: Types.IntType;
kind: "error";
error: GenericError | IntError;
}
/**
* An int-specific error
*
* @Category Elementary types
*/
export type IntError = IntPaddingError;
/**
* A padding error for a signed integer (note padding is not always checked)
*
* @Category Elementary types
*/
export interface IntPaddingError {
/**
* hex string
*/
raw: string;
kind: "IntPaddingError";
paddingType: PaddingType;
}
/**
* An error result for a boolean
*
* @Category Elementary types
*/
export interface BoolErrorResult {
type: Types.BoolType;
kind: "error";
error: GenericError | BoolError;
}
/**
* A bool-specific error
*
* @Category Elementary types
*/
export type BoolError = BoolOutOfRangeError | BoolPaddingError;
/**
* The bool is neither 0 nor 1
*
* @Category Elementary types
*/
export interface BoolOutOfRangeError {
rawAsBN: BN;
kind: "BoolOutOfRangeError";
}
/**
* A padding error for a boolean
*
* @Category Elementary types
*/
export interface BoolPaddingError {
/**
* hex string
*/
raw: string;
kind: "BoolPaddingError";
paddingType: PaddingType;
}
/**
* An error result for a static-length bytestring
*
* @Category Elementary types
*/
export interface BytesStaticErrorResult {
type: Types.BytesTypeStatic;
kind: "error";
error: GenericError | BytesStaticError;
}
/**
* A static-bytestring-specific error
*
* @Category Elementary types
*/
export type BytesStaticError = BytesPaddingError;
/**
* A padding error for a static-length bytestring (note padding is not always checked)
*
* @Category Elementary types
*/
export interface BytesPaddingError {
/**
* hex string
*/
raw: string;
kind: "BytesPaddingError";
paddingType: PaddingType;
}
/**
* An error result for a dynamic-length bytestring
*
* @Category Elementary types
*/
export interface BytesDynamicErrorResult {
type: Types.BytesTypeDynamic;
kind: "error";
error: GenericError | BytesDynamicError;
}
/**
* A dynamic-bytestring-specific error
*
* @Category Elementary types
*/
export type BytesDynamicError = DynamicDataImplementationError;
/**
* An error result for an address
*
* @Category Elementary types
*/
export interface AddressErrorResult {
type: Types.AddressType;
kind: "error";
error: GenericError | AddressError;
}
/**
* A address-specific error
*
* @Category Elementary types
*/
export type AddressError = AddressPaddingError;
/**
* A padding error for an address (note padding is not always checked)
*
* @Category Elementary types
*/
export interface AddressPaddingError {
/**
* hex string; no checksum
*/
raw: string;
kind: "AddressPaddingError";
paddingType: PaddingType;
}
/**
* An error result for a string
*
* @Category Elementary types
*/
export interface StringErrorResult {
type: Types.StringType;
kind: "error";
error: GenericError | StringError;
}
/**
* A string-specific error
*
* @Category Elementary types
*/
export type StringError = DynamicDataImplementationError;
/**
* An error result for a signed fixed-point number
*
* @Category Elementary types
*/
export interface FixedErrorResult {
type: Types.FixedType;
kind: "error";
error: GenericError | FixedError;
}
/**
* An error result for an unsigned fixed-point number
*
* @Category Elementary types
*/
export interface UfixedErrorResult {
type: Types.UfixedType;
kind: "error";
error: GenericError | UfixedError;
}
/**
* A fixed-specific error
*
* @Category Elementary types
*/
export type FixedError = FixedPaddingError;
/**
* A padding error for a signed fixed-point number (note padding is not always checked)
*
* @Category Elementary types
*/
export interface FixedPaddingError {
/**
* hex string
*/
raw: string;
kind: "FixedPaddingError";
paddingType: PaddingType;
}
/**
* A ufixed-specific error
*
* @Category Elementary types
*/
export type UfixedError = UfixedPaddingError;
/**
* A padding error for an unsigned fixed-point number (note padding is not always checked)
*
* @Category Elementary types
*/
export interface UfixedPaddingError {
/**
* hex string
*/
raw: string;
kind: "UfixedPaddingError";
paddingType: PaddingType;
}
/*
* SECTION 3: User-defined elementary types
*/
/**
* An error result for an enum
*
* @Category User-defined elementary types
*/
export interface EnumErrorResult {
type: Types.EnumType;
kind: "error";
error: GenericError | EnumError;
}
/**
* An enum-specific error
*
* @Category User-defined elementary types
*/
export type EnumError =
| EnumOutOfRangeError
| EnumPaddingError
| EnumNotFoundDecodingError;
/**
* The enum is out of range
*
* @Category User-defined elementary types
*/
export interface EnumOutOfRangeError {
kind: "EnumOutOfRangeError";
type: Types.EnumType;
rawAsBN: BN;
}
/**
* A padding error for an enum
*
* @Category Elementary types
*/
export interface EnumPaddingError {
/**
* hex string
*/
raw: string;
type: Types.EnumType;
kind: "EnumPaddingError";
paddingType: PaddingType;
}
/**
* The enum type definition could not be located
*
* @Category User-defined elementary types
*/
export interface EnumNotFoundDecodingError {
kind: "EnumNotFoundDecodingError";
type: Types.EnumType;
rawAsBN: BN;
}
/**
* An error result for a user-defined value type
*
* @Category User-defined elementary types
*/
export interface UserDefinedValueTypeErrorResult {
type: Types.UserDefinedValueTypeType;
kind: "error";
error: GenericError | UserDefinedValueTypeError;
}
/**
* A UDVT-specific error
*
* @Category User-defined elementary types
*/
export type UserDefinedValueTypeError = WrappedError;
/**
* An error result representing something going wrong decoding
* the underlying type when decoding a UDVT
*
* @Category User-defined elementary types
*/
export interface WrappedError {
kind: "WrappedError";
error: BuiltInValueErrorResult;
}
/**
* An error result for a contract
*
* @Category User-defined elementary types
*/
export interface ContractErrorResult {
type: Types.ContractType;
kind: "error";
error: GenericError | ContractError;
}
/**
* A contract-specific error
*
* @Category User-defined elementary types
*/
export type ContractError = ContractPaddingError;
/**
* A padding error for contract (note padding is not always checked)
*
* @Category User-defined elementary types
*/
export interface ContractPaddingError {
/**
* hex string
*/
raw: string;
kind: "ContractPaddingError";
paddingType: PaddingType;
}
/*
* SECTION 4: Container types (including magic)
*/
/**
* An error result for an array
*
* @Category Container types
*/
export interface ArrayErrorResult {
type: Types.ArrayType;
kind: "error";
error: GenericError | ArrayError;
}
/**
* An arrray-specific error
*
* @Category Container types
*/
export type ArrayError = DynamicDataImplementationError;
/**
* An error result for a mapping
*
* @Category Container types
*/
export interface MappingErrorResult {
type: Types.MappingType;
kind: "error";
error: GenericError | MappingError;
}
/**
* A mapping-specific error (there are none)
*
* @Category Container types
*/
export type MappingError = never;
/**
* An error result for a struct
*
* @Category Container types
*/
export interface StructErrorResult {
type: Types.StructType;
kind: "error";
error: GenericError | StructError;
}
/**
* A struct-specific error
*
* @Category Container types
*/
export type StructError = DynamicDataImplementationError;
/**
* An error result for a tuple
*
* @Category Container types
*/
export interface TupleErrorResult {
type: Types.TupleType;
kind: "error";
error: GenericError | TupleError;
}
/**
* A tuple-specific error
*
* @Category Container types
*/
export type TupleError = DynamicDataImplementationError;
/**
* An error result for a magic variable
*
* @Category Special container types (debugger-only)
*/
export interface MagicErrorResult {
type: Types.MagicType;
kind: "error";
error: GenericError | MagicError;
}
/**
* A magic-specific error (there are none)
*
* @Category Special container types (debugger-only)
*/
export type MagicError = never;
/**
* An error result for a type
*
* @Category Special container types (debugger-only)
*/
export interface TypeErrorResult {
type: Types.TypeType;
kind: "error";
error: GenericError | TypeErrorUnion;
}
/**
* An error specific to type values (there are none);
* this isn't called TypeError because that's not legal
*
* @Category Special container types (debugger-only)
*/
export type TypeErrorUnion = never;
/*
* SECTION 5: External functions
*/
/**
* An error result for an external function
*
* @Category Function types
*/
export interface FunctionExternalErrorResult {
type: Types.FunctionExternalType;
kind: "error";
error: GenericError | FunctionExternalError;
}
/**
* An external-function specific error
*
* @Category Function types
*/
export type FunctionExternalError =
| FunctionExternalNonStackPaddingError
| FunctionExternalStackPaddingError;
/**
* This error kind represents a padding error for an external function pointer located anywhere other than the stack.
*
* @Category Function types
*/
export interface FunctionExternalNonStackPaddingError {
/**
* hex string
*/
raw: string;
kind: "FunctionExternalNonStackPaddingError";
paddingType: PaddingType;
}
/**
* This error kind represents a padding error for external function pointer located on the stack.
*
* @Category Function types
*/
export interface FunctionExternalStackPaddingError {
/**
* hex string (no checksum; also a full word long)
*/
rawAddress: string;
/**
* hex string (but a full word long)
*/
rawSelector: string;
kind: "FunctionExternalStackPaddingError";
}
/*
* SECTION 6: Internal functions
*/
/**
* An error result for an internal function
*
* @Category Function types
*/
export interface FunctionInternalErrorResult {
type: Types.FunctionInternalType;
kind: "error";
error: GenericError | FunctionInternalError;
}
/**
* An internal-function specific error
*
* @Category Function types
*/
export type FunctionInternalError =
| FunctionInternalPaddingError
| NoSuchInternalFunctionError
| DeployedFunctionInConstructorError
| MalformedInternalFunctionError;
/**
* A padding error for an internal function
*
* @Category Function types
*/
export interface FunctionInternalPaddingError {
/**
* hex string
*/
raw: string;
kind: "FunctionInternalPaddingError";
paddingType: PaddingType;
}
/**
* Indicates that the function pointer being decoded fails to point to a valid
* function, and also is not one of the default values
*
* @Category Function types
*/
export interface NoSuchInternalFunctionError {
kind: "NoSuchInternalFunctionError";
context: Types.ContractType;
rawInformation: FunctionInternalRawInfo;
}
/**
* Indicates that this is a deployed-style pointer,
* despite the fact that you're in a constructor
*
* @Category Function types
*/
export interface DeployedFunctionInConstructorError {
kind: "DeployedFunctionInConstructorError";
context: Types.ContractType;
rawInformation: FunctionInternalRawInfoPcPair; //will never be index
}
/**
* Used when the deployed PC is zero but the constructor PC
* is nonzero
*
* @Category Function types
*/
export interface MalformedInternalFunctionError {
kind: "MalformedInternalFunctionError";
context: Types.ContractType;
rawInformation: FunctionInternalRawInfoPcPair; //will never be index
}
/*
* SECTION 7: Options
*/
/**
* An options error. This should never happen,
* as options are never decoded, but it's included for
* completeness.
*/
export interface OptionsErrorResult {
type: Types.OptionsType;
kind: "error";
error: GenericError | OptionsError;
}
/**
* The options type has no type-specific errors at the moment
*/
export type OptionsError = never;
/*
* SECTION 8: Generic errors
*/
/**
* A type-non-specific error
*
* @Category Generic errors
*/
export type GenericError =
| UserDefinedTypeNotFoundError
| IndexedReferenceTypeError
| ReadError;
/**
* A read error
*
* @Category Generic errors
*/
export type ReadError =
| UnsupportedConstantError
| ReadErrorStack
| ReadErrorBytes
| ReadErrorStorage
| StorageNotSuppliedError
| UnusedImmutableError
| CodeNotSuppliedError;
/**
* An error resulting from overlarge length or pointer values
*
* @Category Generic errors
*/
export type DynamicDataImplementationError =
| OverlongArraysAndStringsNotImplementedError
| OverlargePointersNotImplementedError;
/**
* An error that may occur in a component other than the main
* core of the decoder itself and thus may need to get thrown to it
*
* @Category Generic errors
*/
export type ErrorForThrowing = UserDefinedTypeNotFoundError | ReadError;
/**
* Used when decoding an indexed parameter of reference (or tuple) type. These
* can't meaningfully be decoded, so instead they decode to an error, sorry.
*
* @Category Generic errors
*/
export interface IndexedReferenceTypeError {
kind: "IndexedReferenceTypeError";
type: Types.ReferenceType | Types.TupleType;
/**
* hex string
*/
raw: string;
}
/**
* An error for when can't find the definition info for a user-defined type
*
* @Category Generic errors
*/
export interface UserDefinedTypeNotFoundError {
kind: "UserDefinedTypeNotFoundError";
type: Types.UserDefinedType;
}
/**
* An error for an unsupported type of constant (this counts as a read error)
*
* @Category Generic errors
*/
export interface UnsupportedConstantError {
kind: "UnsupportedConstantError";
definition: Ast.AstNode;
}
/**
* Read error on the stack
*
* @Category Generic errors
*/
export interface ReadErrorStack {
kind: "ReadErrorStack";
from: number;
to: number;
}
/**
* A byte-based location
*/
export type BytesLocation =
| "memory"
| "calldata"
| "eventdata"
| "returndata"
| "code";
/**
* Read error in a byte-based location (memory, calldata, etc)
*
* @Category Generic errors
*/
export interface ReadErrorBytes {
kind: "ReadErrorBytes";
location: BytesLocation;
start: number;
length: number;
}
/**
* Read error in storage
*
* @Category Generic errors
*/
export interface ReadErrorStorage {
kind: "ReadErrorStorage";
range: Storage.Range;
}
/**
* A read error in storage, but one triggered deliberately to indicate
* that that particular area of storage is unknown, rather than due to
* an unexpected error condition. This error is triggered by passing
* null in response to a storage request.
*
* @Category Generic errors
*/
export interface StorageNotSuppliedError {
kind: "StorageNotSuppliedError";
slot: BN;
}
/**
* Attempting to read an immutable that is never stored anywhere
*
* @Category Generic errors
*/
export interface UnusedImmutableError {
kind: "UnusedImmutableError";
}
/**
* A read error in code, but one triggered deliberately to indicate that
* bytecode is unknown, rather than due to an unexpected error condition. This
* error is triggered by passing null in response to a storage request.
*
* @Category Generic errors
*/
export interface CodeNotSuppliedError {
kind: "CodeNotSuppliedError";
address: string;
}
/**
* Error for array/string/bytestring having length bigger than a JS number
*
* @Category Generic errors
*/
export interface OverlongArraysAndStringsNotImplementedError {
kind: "OverlongArraysAndStringsNotImplementedError";
lengthAsBN: BN;
dataLength?: number; //only included when the special strict mode check fails
}
/**
* Error for dynamic type being represented by pointer bigger than a JS number
*
* @Category Generic errors
*/
export interface OverlargePointersNotImplementedError {
kind: "OverlargePointersNotImplementedError";
pointerAsBN: BN;
}
/* SECTION 9: Internal use errors */
/* you should never see these returned.
* they are only for internal use. */
/**
* Internal-use error
*
* @Category Internal-use errors
*/
export type InternalUseError =
| OverlongArrayOrStringStrictModeError
| InternalFunctionInABIError
| ReEncodingMismatchError;
/**
* Error for the stricter length check in strict mode
*
* @Category Internal-use errors
*/
export interface OverlongArrayOrStringStrictModeError {
kind: "OverlongArrayOrStringStrictModeError";
lengthAsBN: BN;
dataLength: number;
}
/**
* This should never come up, but just to be sure...
*
* @Category Internal-use errors
*/
export interface InternalFunctionInABIError {
kind: "InternalFunctionInABIError";
}
/**
* This isn't really an error that one can get as part of a `Result`, but we
* need something for when re-encoding doesn't match and we're decoding a
* transaction (since there we have to error instead of just skipping).
*
* @Category Internal-use errors
*/
export interface ReEncodingMismatchError {
kind: "ReEncodingMismatchError";
data: Uint8Array;
reEncodedData: Uint8Array;
}