Skip to main content

clarity/
error.rs

1use std::fmt;
2use std::num::ParseIntError;
3use std::str::Utf8Error;
4
5use num256::Uint256;
6
7/// Custom error implementation that describes possible
8/// error states.
9///
10/// This is shared by a whole crate.
11#[derive(Debug)]
12pub enum Error {
13    InvalidNetworkId,
14    InvalidV,
15    InvalidR,
16    InvalidS,
17    InvalidSignatureValues,
18    ZeroPrivKey,
19    InvalidPrivKeyLength {
20        got: usize,
21        expected: usize,
22    },
23    DecodePrivKey(secp256k1::Error),
24    DecodeRecoveryId(secp256k1::Error),
25    ParseMessage(secp256k1::Error),
26    ParseRecoverableSignature(secp256k1::Error),
27    RecoverSignature(secp256k1::Error),
28    InvalidAddressLength {
29        got: usize,
30        expected: usize,
31    },
32    InvalidUtf8(Utf8Error),
33    InvalidHex(ParseIntError),
34    InvalidEip55,
35    InvalidCallError(String),
36    InvalidSignatureLength,
37    SerializeRlp,
38    DeserializeRlp,
39    NoSignature,
40    UnknownTxType(Uint256),
41    AbiInputTooShort {
42        expected: usize,
43        actual: usize,
44    },
45    AddressParseError,
46    IntegerParseError,
47    NonceTooLarge,
48    GasCostOverflow,
49    MaxPriorityFeeExceedsMaxFee,
50    ZeroMaxPriorityFee,
51    GasLimitTooLow {
52        gas_limit: Uint256,
53        intrinsic_gas: Uint256,
54    },
55    GasLimitTooHigh,
56}
57
58impl fmt::Display for Error {
59    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
60        match self {
61            Error::InvalidNetworkId => write!(f, "Invalid network id"),
62            Error::InvalidV => write!(f, "Invalid V value"),
63            Error::InvalidR => write!(f, "Invalid R value"),
64            Error::InvalidS => write!(f, "Invalid S value"),
65            Error::InvalidSignatureValues => write!(f, "Invalid signature values"),
66            Error::ZeroPrivKey => write!(f, "Zero priv key cannot sign"),
67            Error::InvalidPrivKeyLength { got, expected } => write!(
68                f,
69                "Invalid private key length, got {got} expected {expected}"
70            ),
71            Error::DecodePrivKey(_) => write!(f, "Failed to decode private key"),
72            Error::DecodeRecoveryId(_) => write!(f, "Failed to decode recovery id"),
73            Error::ParseMessage(_) => write!(f, "Failed to parse message"),
74            Error::ParseRecoverableSignature(_) => {
75                write!(f, "Failed to parse recoverable signature")
76            }
77            Error::RecoverSignature(_) => write!(f, "Failed to recover signature"),
78            Error::InvalidAddressLength { got, expected } => {
79                write!(f, "Invalid address length, got {got}, expected {expected}")
80            }
81            Error::InvalidUtf8(_) => write!(f, "Failed to parse bytes as utf8"),
82            Error::InvalidHex(_) => write!(f, "Invalid hex character"),
83            Error::InvalidEip55 => write!(f, "Invalid EIP-55 Address encoding"),
84            Error::InvalidCallError(val) => write!(f, "Invalid function call {val}"),
85            Error::InvalidSignatureLength => write!(f, "Signature should be exactly 65 bytes long"),
86            Error::SerializeRlp => write!(f, "failed to serialize using RLP-encoding"),
87            Error::DeserializeRlp => write!(f, "failed to deserialize using RLP-encoding"),
88            Error::NoSignature => write!(f, "This transaction does not have a signature attached"),
89            Error::UnknownTxType(t) => write!(f, "Unsupported Ethereum transaction type {}", t),
90            Error::AbiInputTooShort {
91                expected,
92                actual: got,
93            } => write!(
94                f,
95                "ABI input too short, expected at least {expected} bytes, got {got} bytes"
96            ),
97            Error::AddressParseError => write!(f, "Failed to parse address"),
98            Error::IntegerParseError => write!(f, "Failed to parse integer"),
99            Error::NonceTooLarge => write!(f, "Nonce must be less than 2^64 - 1"),
100            Error::GasCostOverflow => write!(
101                f,
102                "Gas cost overflow: gas_limit * gas_price exceeds maximum"
103            ),
104            Error::MaxPriorityFeeExceedsMaxFee => {
105                write!(f, "max_priority_fee_per_gas exceeds max_fee_per_gas")
106            }
107            Error::ZeroMaxPriorityFee => write!(f, "max_priority_fee_per_gas must be non-zero"),
108            Error::GasLimitTooLow {
109                gas_limit,
110                intrinsic_gas,
111            } => write!(
112                f,
113                "Gas limit {gas_limit} is below intrinsic gas {intrinsic_gas}"
114            ),
115            Error::GasLimitTooHigh => write!(f, "Gas limit exceeds 2^64 - 1"),
116        }
117    }
118}
119
120impl std::error::Error for Error {
121    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
122        match self {
123            Error::DecodePrivKey(inner) => Some(inner),
124            Error::DecodeRecoveryId(inner) => Some(inner),
125            Error::ParseMessage(inner) => Some(inner),
126            Error::ParseRecoverableSignature(inner) => Some(inner),
127            Error::RecoverSignature(inner) => Some(inner),
128            Error::InvalidHex(inner) => Some(inner),
129            Error::InvalidUtf8(inner) => Some(inner),
130            _ => None,
131        }
132    }
133}
134
135impl From<Utf8Error> for Error {
136    fn from(e: Utf8Error) -> Self {
137        Error::InvalidUtf8(e)
138    }
139}
140
141impl From<ParseIntError> for Error {
142    fn from(e: ParseIntError) -> Self {
143        Error::InvalidHex(e)
144    }
145}