1use borsh::{BorshDeserialize, BorshSerialize};
5use serde::{Deserialize, Serialize};
6use thiserror::Error;
7
8use crate::HeadersError;
9
10#[derive(
12 Clone, Debug, Eq, Error, PartialEq, Serialize, Deserialize, BorshSerialize, BorshDeserialize,
13)]
14pub enum RexError {
15 #[error("Missing required parameter: {param}")]
16 MissingParameter { param: String },
17
18 #[error("Invalid parameter '{param}': {reason}")]
19 InvalidParameter { param: String, reason: String },
20
21 #[error("Failed to decode {encoding} for parameter '{param}': {reason}")]
22 DecodeError {
23 param: String,
24 encoding: String,
25 reason: String,
26 },
27
28 #[error("Invalid URL: {reason}")]
29 InvalidUrl { reason: String },
30
31 #[error("URL validation failed: {reason}")]
32 UrlValidationError { reason: String },
33
34 #[error("HTTP request failed: {message}{}", reason.as_ref().map(|r| format!(", {}", r)).unwrap_or_default()
35 )]
36 HttpRequestFailed {
37 message: String,
38 reason: Option<String>,
39 },
40
41 #[error("HTTP {status} error: {reason}")]
42 HttpStatusError { status: u16, reason: String },
43
44 #[error("Response size exceeds maximum of {max_size} bytes")]
45 ResponseTooLarge { max_size: usize },
46
47 #[error("Request body size of {size} bytes exceeds maximum of {max_size} bytes")]
48 RequestBodyTooLarge { size: usize, max_size: usize },
49
50 #[error("Filter error: {reason}")]
51 FilterError { reason: String },
52
53 #[error("Timeout after {duration_ms}ms")]
54 Timeout { duration_ms: u64 },
55
56 #[error("All {attempts} retry attempts failed: {reason}")]
57 RetriesExhausted { attempts: u8, reason: String },
58
59 #[error("JSON parsing error: {reason}")]
60 JsonError { reason: String },
61
62 #[error("No valid data sources available")]
63 NoDataSources,
64
65 #[error("Failed to decrypt secret payload: {reason}")]
66 SecretDecryptionFailed { reason: String },
67
68 #[error("Invalid secret payload format: {reason}")]
69 InvalidSecretPayload { reason: String },
70
71 #[error("Provided REX output size is too small: {provided}")]
72 RexOutputSizeTooSmall { provided: usize },
73
74 #[error("Invalid REX duty input, err: {0}")]
75 InvalidRexDutyInput(String),
76
77 #[error("Connection error: {reason}")]
78 ConnectionError { reason: String },
79
80 #[error("WebSocket error: {message}")]
81 WebSocketError { message: String },
82
83 #[error("DKG input validation failed: {reason}")]
85 DkgValidationError { reason: String },
86
87 #[error("DKG cryptographic operation failed ({operation}): {reason}")]
88 DkgCryptoError { operation: String, reason: String },
89
90 #[error("DKG handler not implemented: {handler}")]
91 DkgNotImplemented { handler: String },
92
93 #[error("DKG genesis failed: {reason}")]
94 DkgGenesisError { reason: String },
95
96 #[error("DKG share installation failed: {reason}")]
97 DkgInstallShareError { reason: String },
98
99 #[error("DKG share decryption (HPKE) failed for dealer {dealer_index}: {reason}")]
100 DkgDecryptionError { dealer_index: u16, reason: String },
101
102 #[error("DKG share verification failed for dealer {dealer_index}")]
103 DkgVerificationError { dealer_index: u16 },
104
105 #[error("DKG partial decryption failed: {reason}")]
106 DkgPartialDecryptError { reason: String },
107
108 #[error("DKG TPM sealing failed (fast-restart recovery unavailable): {reason}")]
109 DkgSealingError { reason: String },
110
111 #[error("DKG combine error: {reason}")]
112 DkgCombineError { reason: String },
113
114 #[error("DKG AEAD decryption failed: invalid ciphertext or authentication tag")]
115 DkgAeadDecryptFailed,
116
117 #[error("DKG key derivation (HKDF) failed")]
118 DkgHkdfExpandFailed,
119
120 #[error("DKG invalid key length")]
121 DkgInvalidKeyLength,
122 #[error("WASM execution error: {reason}")]
123 WasmExecutionError { reason: String },
124}
125
126impl From<HeadersError> for RexError {
127 fn from(err: HeadersError) -> Self {
128 match err {
129 HeadersError::DecodeError {
130 param,
131 encoding,
132 reason,
133 } => Self::DecodeError {
134 param,
135 encoding,
136 reason,
137 },
138 HeadersError::JsonError { reason } => Self::JsonError { reason },
139 }
140 }
141}