neo3/
neo_error.rs

1//! # Neo Error Types (v0.1.5)
2//!
3//! This module provides a unified error handling system for the NeoRust SDK.
4//!
5//! ## Overview
6//!
7//! The `NeoError` enum acts as the central error type for the entire SDK, providing
8//! specific error categories and conversion from various error types used throughout
9//! the codebase. This approach simplifies error handling by allowing all operations
10//! to return a consistent error type.
11//!
12//! ## Usage
13//!
14//! ```rust
15//! use neo::prelude::*;
16//! use std::str::FromStr;
17//!
18//! fn example() -> Result<(), NeoError> {
19//!     // NeoError can be created directly
20//!     if some_condition {
21//!         return Err(NeoError::InvalidAddress);
22//!     }
23//!     
24//!     // Or it can be created with a message
25//!     let error_msg = "Invalid parameter value";
26//!     return Err(NeoError::IllegalArgument(error_msg.to_string()));
27//!     
28//!     // Standard library errors are also converted automatically
29//!     let io_result = std::fs::File::open("non_existent_file");
30//!     let file = io_result?; // This will return NeoError::IoError if the file doesn't exist
31//!     
32//!     Ok(())
33//! }
34//! ```
35
36use thiserror::Error;
37
38/// Comprehensive error type for the NeoRust SDK.
39///
40/// This enum provides a unified error handling system for all operations in the SDK.
41/// It includes specific error types for different categories of errors and implements
42/// conversions from various error types used throughout the codebase.
43#[derive(Error, Debug)]
44pub enum NeoError {
45	/// An error for illegal or invalid argument values.
46	#[error("Illegal argument: {0}")]
47	IllegalArgument(String),
48	
49	/// An error that occurs during deserialization.
50	#[error("Deserialization error: {0}")]
51	Deserialization(String),
52	
53	/// An error for illegal state conditions.
54	#[error("Illegal state: {0}")]
55	IllegalState(String),
56	
57	/// An error for index out of bounds conditions.
58	#[error("Index out of bounds: {0}")]
59	IndexOutOfBounds(String),
60	
61	/// An error for invalid configuration settings.
62	#[error("Invalid configuration: {0}")]
63	InvalidConfiguration(String),
64	
65	/// A general runtime error.
66	#[error("Runtime error: {0}")]
67	Runtime(String),
68	
69	/// An error for invalid data.
70	#[error("Invalid data: {0}")]
71	InvalidData(String),
72	
73	/// An error for unsupported operations.
74	#[error("Unsupported operation: {0}")]
75	UnsupportedOperation(String),
76	
77	/// A general transaction error.
78	#[error("Transaction error: {0}")]
79	Transaction(String),
80	
81	/// An error for invalid scripts.
82	#[error("Invalid script: {0}")]
83	InvalidScript(String),
84	
85	/// An error for invalid format.
86	#[error("Invalid format")]
87	InvalidFormat,
88	
89	/// An error indicating that NeoRust has not been initialized.
90	#[error("neo-rs not initialized")]
91	NeoNotInitialized,
92	
93	/// An error related to smart contracts.
94	#[error("Contract error: {0}")]
95	ContractError(#[from] ContractError),
96	
97	/// An error for wallet-related issues.
98	#[error("Wallet error: {0}")]
99	WalletError(#[from] WalletError),
100	
101	/// An error for signing-related issues.
102	#[error("Sign error: {0}")]
103	SignError(#[from] SignError),
104	
105	/// A general transaction error.
106	#[error("Transaction error: {0}")]
107	TransactionError(#[from] TransactionError),
108	
109	/// An error for unexpected returned types.
110	#[error("Unexpected returned type")]
111	UnexpectedReturnType,
112	
113	/// An error for invalid private keys.
114	#[error("Invalid private key")]
115	InvalidPrivateKey,
116	
117	/// An error for invalid public keys.
118	#[error("Invalid public key")]
119	InvalidPublicKey,
120	
121	/// An error for invalid addresses.
122	#[error("Invalid address")]
123	InvalidAddress,
124	
125	/// An error for invalid signatures.
126	#[error("Invalid signature")]
127	InvalidSignature,
128	
129	/// An error for invalid encoding.
130	#[error("Invalid encoding {0}")]
131	InvalidEncoding(String),
132	
133	/// An error for invalid op codes.
134	#[error("Invalid op code")]
135	InvalidOpCode,
136	
137	/// An error for numeric overflow.
138	#[error("Numeric overflow")]
139	NumericOverflow,
140	
141	/// An error for WIF (Wallet Import Format) issues.
142	#[error("Wif error {0}")]
143	WifError(String),
144	
145	/// An error for provider-related issues.
146	#[error("Provider error: {0}")]
147	ProviderError(#[from] ProviderError),
148	
149	/// An error for codec-related issues.
150	#[error("Codec error: {0}")]
151	CodecError(#[from] CodecError),
152	
153	/// An error for type-related issues.
154	#[error("Type error: {0}")]
155	TypeError(#[from] TypeError),
156	
157	/// An error for protocol-related issues.
158	#[error("Protocol error: {0}")]
159	ProtocolError(#[from] ProtocolError),
160	
161	/// An error for JSON RPC-related issues.
162	#[error("JSON RPC error: {0}")]
163	JsonRpcError(String),
164	
165	/// An error for IO-related issues.
166	#[error("IO error: {0}")]
167	IoError(#[from] std::io::Error),
168	
169	/// An error for serialization-related issues.
170	#[error("Serialization error: {0}")]
171	SerializationError(String),
172}
173
174impl Into<TransactionError> for NeoError {
175	fn into(self) -> TransactionError {
176		TransactionError::TransactionConfiguration(self.to_string())
177	}
178}
179
180impl From<serde_json::Error> for NeoError {
181	fn from(err: serde_json::Error) -> Self {
182		NeoError::SerializationError(err.to_string())
183	}
184}
185
186impl From<String> for NeoError {
187	fn from(err: String) -> Self {
188		NeoError::IllegalState(err)
189	}
190}
191
192impl From<&str> for NeoError {
193	fn from(err: &str) -> Self {
194		NeoError::IllegalState(err.to_string())
195	}
196}
197
198use crate::builder::{BuilderError, TransactionError};
199use crate::codec::CodecError;
200use crate::crypto::{CryptoError, Nep2Error, SignError};
201use crate::neo_clients::ProviderError;
202use crate::neo_contract::ContractError;
203use crate::neo_protocol::ProtocolError;
204use crate::neo_wallets::WalletError;
205use crate::TypeError;
206
207impl From<BuilderError> for NeoError {
208	fn from(err: BuilderError) -> Self {
209		match err {
210			BuilderError::InvalidScript(msg) => NeoError::InvalidScript(msg),
211			BuilderError::InvalidOperation =>
212				NeoError::UnsupportedOperation("Invalid operation".to_string()),
213			BuilderError::InvalidArgument =>
214				NeoError::IllegalArgument("Invalid argument".to_string()),
215			BuilderError::InvalidState => NeoError::IllegalState("Invalid state".to_string()),
216			BuilderError::InvalidInvocation =>
217				NeoError::IllegalState("Invalid invocation".to_string()),
218			BuilderError::StackOverflow => NeoError::Runtime("Stack overflow".to_string()),
219			BuilderError::OutOfGas => NeoError::Runtime("Out of gas".to_string()),
220			BuilderError::OutOfMemory => NeoError::Runtime("Out of memory".to_string()),
221			BuilderError::OutOfCycles => NeoError::Runtime("Out of cycles".to_string()),
222			BuilderError::UnknownError => NeoError::Runtime("Unknown error".to_string()),
223			BuilderError::UnsupportedOperation(msg) => NeoError::UnsupportedOperation(msg),
224			BuilderError::SignerConfiguration(msg) =>
225				NeoError::IllegalState(format!("Signer configuration error: {}", msg)),
226			BuilderError::TransactionConfiguration(msg) => NeoError::Transaction(msg),
227			BuilderError::InvalidConfiguration(msg) => NeoError::InvalidConfiguration(msg),
228			BuilderError::TooManySigners(msg) =>
229				NeoError::IllegalState(format!("Too many signers: {}", msg)),
230			BuilderError::IllegalState(msg) => NeoError::IllegalState(msg),
231			BuilderError::IllegalArgument(msg) => NeoError::IllegalArgument(msg),
232			BuilderError::CodecError(err) => NeoError::CodecError(err),
233			BuilderError::CryptoError(err) => NeoError::from(err),
234			BuilderError::ProviderError(err) => NeoError::ProviderError(err),
235			BuilderError::TransactionError(err) => NeoError::TransactionError(*err),
236		}
237	}
238}
239
240impl From<CryptoError> for NeoError {
241	fn from(err: CryptoError) -> Self {
242		match err {
243			CryptoError::InvalidPassphrase(msg) =>
244				NeoError::IllegalArgument(format!("Invalid passphrase: {}", msg)),
245			CryptoError::InvalidFormat(msg) => NeoError::InvalidFormat,
246			CryptoError::HeaderOutOfRange(byte) =>
247				NeoError::IllegalArgument(format!("Header byte out of range: {}", byte)),
248			CryptoError::RecoverFailed =>
249				NeoError::IllegalState("Could not recover public key from signature".to_string()),
250			CryptoError::InvalidPublicKey => NeoError::InvalidPublicKey,
251			CryptoError::InvalidPrivateKey => NeoError::InvalidPrivateKey,
252			CryptoError::P256Error(err) => NeoError::IllegalState(format!("P256 error: {}", err)),
253			CryptoError::SigningError => NeoError::SignError(SignError::RecoverFailed),
254			CryptoError::SignatureVerificationError => NeoError::InvalidSignature,
255			CryptoError::FromHexError(err) =>
256				NeoError::InvalidEncoding(format!("Hex error: {}", err)),
257			CryptoError::DecryptionError(msg) =>
258				NeoError::IllegalState(format!("Decryption error: {}", msg)),
259			CryptoError::KeyError(msg) => NeoError::IllegalState(format!("Key error: {}", msg)),
260		}
261	}
262}
263
264impl From<Nep2Error> for NeoError {
265	fn from(err: Nep2Error) -> Self {
266		match err {
267			Nep2Error::InvalidPassphrase(msg) =>
268				NeoError::IllegalArgument(format!("Invalid NEP-2 passphrase: {}", msg)),
269			Nep2Error::InvalidFormat(msg) =>
270				NeoError::InvalidEncoding(format!("Invalid NEP-2 format: {}", msg)),
271		}
272	}
273}
274
275// Implement From for reqwest::Error to handle HTTP errors
276impl From<reqwest::Error> for NeoError {
277	fn from(err: reqwest::Error) -> Self {
278		NeoError::IoError(std::io::Error::new(
279			std::io::ErrorKind::Other,
280			format!("HTTP error: {}", err),
281		))
282	}
283}
284
285// Implement From for hex::FromHexError to handle hex decoding errors
286impl From<hex::FromHexError> for NeoError {
287	fn from(err: hex::FromHexError) -> Self {
288		NeoError::InvalidEncoding(format!("Hex error: {}", err))
289	}
290}
291
292// Implement From for std::num::ParseIntError to handle integer parsing errors
293impl From<std::num::ParseIntError> for NeoError {
294	fn from(err: std::num::ParseIntError) -> Self {
295		NeoError::IllegalArgument(format!("Integer parsing error: {}", err))
296	}
297}
298
299// Implement From for std::str::Utf8Error to handle UTF-8 decoding errors
300impl From<std::str::Utf8Error> for NeoError {
301	fn from(err: std::str::Utf8Error) -> Self {
302		NeoError::InvalidEncoding(format!("UTF-8 error: {}", err))
303	}
304}