Skip to main content

rialo_types/
error.rs

1// Copyright (c) Subzero Labs, Inc.
2// SPDX-License-Identifier: Apache-2.0
3
4use borsh::{BorshDeserialize, BorshSerialize};
5use serde::{Deserialize, Serialize};
6use thiserror::Error;
7
8use crate::HeadersError;
9
10/// Represents errors that can occur during REX processing.
11#[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    // DKG-specific errors
84    #[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}