feat: use thiserror library to handle error creation
This commit is contained in:
parent
06fa9d751b
commit
61e58240fc
9
bdk-ffi/Cargo.lock
generated
9
bdk-ffi/Cargo.lock
generated
@ -161,6 +161,7 @@ dependencies = [
|
||||
"bdk",
|
||||
"bdk_esplora",
|
||||
"bdk_file_store",
|
||||
"thiserror",
|
||||
"uniffi",
|
||||
]
|
||||
|
||||
@ -883,18 +884,18 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.56"
|
||||
version = "1.0.58"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d54378c645627613241d077a3a79db965db602882668f9136ac42af9ecb730ad"
|
||||
checksum = "03468839009160513471e86a034bb2c5c0e4baae3b43f79ffc55c4a5427b3297"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.56"
|
||||
version = "1.0.58"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fa0faa943b50f3db30a20aa7e265dbc66076993efed8463e8de414e5d06d3471"
|
||||
checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -24,6 +24,7 @@ bdk_esplora = { version = "0.9.0", default-features = false, features = ["std",
|
||||
bdk_file_store = { version = "0.7.0" }
|
||||
|
||||
uniffi = { version = "=0.26.1" }
|
||||
thiserror = "1.0.58"
|
||||
|
||||
[build-dependencies]
|
||||
uniffi = { version = "=0.26.1", features = ["build"] }
|
||||
|
@ -3,8 +3,6 @@ use crate::bitcoin::OutPoint;
|
||||
use bdk::chain::tx_graph::CalculateFeeError as BdkCalculateFeeError;
|
||||
use bdk_esplora::esplora_client::Error as BdkEsploraError;
|
||||
|
||||
use std::fmt;
|
||||
|
||||
use bdk::bitcoin::Network;
|
||||
use bdk::descriptor::DescriptorError;
|
||||
use bdk::wallet::error::{BuildFeeBumpError, CreateTxError};
|
||||
@ -14,77 +12,93 @@ use bdk_file_store::FileError as BdkFileError;
|
||||
use bdk_file_store::IterError;
|
||||
use std::convert::Infallible;
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
pub enum Alpha3Error {
|
||||
#[error("generic error in ffi")]
|
||||
Generic,
|
||||
}
|
||||
|
||||
impl fmt::Display for Alpha3Error {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
Alpha3Error::Generic => write!(f, "Error in FFI"),
|
||||
}
|
||||
}
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
pub enum CalculateFeeError {
|
||||
#[error("missing transaction output: {out_points:?}")]
|
||||
MissingTxOut { out_points: Vec<OutPoint> },
|
||||
|
||||
#[error("negative fee value: {fee}")]
|
||||
NegativeFee { fee: i64 },
|
||||
}
|
||||
|
||||
impl std::error::Error for Alpha3Error {}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
pub enum WalletCreationError {
|
||||
// Errors coming from the FileError enum
|
||||
Io {
|
||||
e: String,
|
||||
},
|
||||
InvalidMagicBytes {
|
||||
got: Vec<u8>,
|
||||
expected: Vec<u8>,
|
||||
},
|
||||
#[error("io error trying to read file: {e}")]
|
||||
Io { e: String },
|
||||
|
||||
#[error("file has invalid magic bytes: expected={expected:?} got={got:?}")]
|
||||
InvalidMagicBytes { got: Vec<u8>, expected: Vec<u8> },
|
||||
|
||||
// Errors coming from the NewOrLoadError enum
|
||||
#[error("error with descriptor")]
|
||||
Descriptor,
|
||||
|
||||
#[error("failed to write to persistence")]
|
||||
Write,
|
||||
|
||||
#[error("failed to load from persistence")]
|
||||
Load,
|
||||
|
||||
#[error("wallet is not initialized, persistence backend is empty")]
|
||||
NotInitialized,
|
||||
|
||||
#[error("loaded genesis hash does not match the expected one")]
|
||||
LoadedGenesisDoesNotMatch,
|
||||
|
||||
#[error("loaded network type is not {expected}, got {got:?}")]
|
||||
LoadedNetworkDoesNotMatch {
|
||||
expected: Network,
|
||||
got: Option<Network>,
|
||||
},
|
||||
}
|
||||
|
||||
impl fmt::Display for WalletCreationError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
Self::Io { e } => write!(f, "io error trying to read file: {}", e),
|
||||
Self::InvalidMagicBytes { got, expected } => write!(
|
||||
f,
|
||||
"file has invalid magic bytes: expected={:?} got={:?}",
|
||||
expected, got,
|
||||
),
|
||||
Self::Descriptor => write!(f, "error with descriptor"),
|
||||
Self::Write => write!(f, "failed to write to persistence"),
|
||||
Self::Load => write!(f, "failed to load from persistence"),
|
||||
Self::NotInitialized => {
|
||||
write!(f, "wallet is not initialized, persistence backend is empty")
|
||||
}
|
||||
Self::LoadedGenesisDoesNotMatch => {
|
||||
write!(f, "loaded genesis hash does not match the expected one")
|
||||
}
|
||||
Self::LoadedNetworkDoesNotMatch { expected, got } => {
|
||||
write!(f, "loaded network type is not {}, got {:?}", expected, got)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
pub enum EsploraError {
|
||||
#[error("ureq error: {error_message}")]
|
||||
Ureq { error_message: String },
|
||||
|
||||
impl std::error::Error for WalletCreationError {}
|
||||
#[error("ureq transport error: {error_message}")]
|
||||
UreqTransport { error_message: String },
|
||||
|
||||
#[error("http error with status code: {status_code}")]
|
||||
Http { status_code: u16 },
|
||||
|
||||
#[error("io error: {error_message}")]
|
||||
Io { error_message: String },
|
||||
|
||||
#[error("no header found in the response")]
|
||||
NoHeader,
|
||||
|
||||
#[error("parsing error: {error_message}")]
|
||||
Parsing { error_message: String },
|
||||
|
||||
#[error("bitcoin encoding error: {error_message}")]
|
||||
BitcoinEncoding { error_message: String },
|
||||
|
||||
#[error("hex decoding error: {error_message}")]
|
||||
Hex { error_message: String },
|
||||
|
||||
#[error("transaction not found")]
|
||||
TransactionNotFound,
|
||||
|
||||
#[error("header height {height} not found")]
|
||||
HeaderHeightNotFound { height: u32 },
|
||||
|
||||
#[error("header hash not found")]
|
||||
HeaderHashNotFound,
|
||||
}
|
||||
|
||||
impl From<BdkFileError> for WalletCreationError {
|
||||
fn from(error: BdkFileError) -> Self {
|
||||
match error {
|
||||
BdkFileError::Io(_) => WalletCreationError::Io {
|
||||
e: "io error trying to read file".to_string(),
|
||||
},
|
||||
BdkFileError::Io(e) => WalletCreationError::Io { e: e.to_string() },
|
||||
BdkFileError::InvalidMagicBytes { got, expected } => {
|
||||
WalletCreationError::InvalidMagicBytes { got, expected }
|
||||
}
|
||||
@ -157,23 +171,6 @@ impl From<CreateTxError<std::io::Error>> for Alpha3Error {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum CalculateFeeError {
|
||||
MissingTxOut { out_points: Vec<OutPoint> },
|
||||
NegativeFee { fee: i64 },
|
||||
}
|
||||
|
||||
impl fmt::Display for CalculateFeeError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
CalculateFeeError::MissingTxOut { out_points } => {
|
||||
write!(f, "Missing transaction output: {:?}", out_points)
|
||||
}
|
||||
CalculateFeeError::NegativeFee { fee } => write!(f, "Negative fee value: {}", fee),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<BdkCalculateFeeError> for CalculateFeeError {
|
||||
fn from(error: BdkCalculateFeeError) -> Self {
|
||||
match error {
|
||||
@ -185,53 +182,6 @@ impl From<BdkCalculateFeeError> for CalculateFeeError {
|
||||
}
|
||||
}
|
||||
|
||||
impl std::error::Error for CalculateFeeError {}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum EsploraError {
|
||||
Ureq { error_message: String },
|
||||
UreqTransport { error_message: String },
|
||||
Http { status_code: u16 },
|
||||
Io { error_message: String },
|
||||
NoHeader,
|
||||
Parsing { error_message: String },
|
||||
BitcoinEncoding { error_message: String },
|
||||
Hex { error_message: String },
|
||||
TransactionNotFound,
|
||||
HeaderHeightNotFound { height: u32 },
|
||||
HeaderHashNotFound,
|
||||
}
|
||||
|
||||
impl fmt::Display for EsploraError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
EsploraError::Ureq { error_message } => write!(f, "Ureq error: {}", error_message),
|
||||
EsploraError::UreqTransport { error_message } => {
|
||||
write!(f, "Ureq transport error: {}", error_message)
|
||||
}
|
||||
EsploraError::Http { status_code } => {
|
||||
write!(f, "HTTP error with status code: {}", status_code)
|
||||
}
|
||||
EsploraError::Io { error_message } => write!(f, "IO error: {}", error_message),
|
||||
EsploraError::NoHeader => write!(f, "No header found in the response"),
|
||||
EsploraError::Parsing { error_message } => {
|
||||
write!(f, "Parsing error: {}", error_message)
|
||||
}
|
||||
EsploraError::BitcoinEncoding { error_message } => {
|
||||
write!(f, "Bitcoin encoding error: {}", error_message)
|
||||
}
|
||||
EsploraError::Hex { error_message } => {
|
||||
write!(f, "Hex decoding error: {}", error_message)
|
||||
}
|
||||
EsploraError::TransactionNotFound => write!(f, "Transaction not found"),
|
||||
EsploraError::HeaderHeightNotFound { height } => {
|
||||
write!(f, "Header height {} not found", height)
|
||||
}
|
||||
EsploraError::HeaderHashNotFound => write!(f, "Header hash not found"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<BdkEsploraError> for EsploraError {
|
||||
fn from(error: BdkEsploraError) -> Self {
|
||||
match error {
|
||||
@ -264,8 +214,6 @@ impl From<BdkEsploraError> for EsploraError {
|
||||
}
|
||||
}
|
||||
|
||||
impl std::error::Error for EsploraError {}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use crate::error::EsploraError;
|
||||
@ -290,7 +238,7 @@ mod test {
|
||||
let error = CalculateFeeError::MissingTxOut { out_points };
|
||||
|
||||
let expected_message: String = format!(
|
||||
"Missing transaction output: [{:?}, {:?}]",
|
||||
"missing transaction output: [{:?}, {:?}]",
|
||||
OutPoint {
|
||||
txid: "0000000000000000000000000000000000000000000000000000000000000001"
|
||||
.to_string(),
|
||||
@ -310,7 +258,7 @@ mod test {
|
||||
fn test_error_negative_fee() {
|
||||
let error = CalculateFeeError::NegativeFee { fee: -100 };
|
||||
|
||||
assert_eq!(error.to_string(), "Negative fee value: -100");
|
||||
assert_eq!(error.to_string(), "negative fee value: -100");
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -320,49 +268,49 @@ mod test {
|
||||
EsploraError::Ureq {
|
||||
error_message: "Network error".to_string(),
|
||||
},
|
||||
"Ureq error: Network error",
|
||||
"ureq error: Network error",
|
||||
),
|
||||
(
|
||||
EsploraError::UreqTransport {
|
||||
error_message: "Timeout occurred".to_string(),
|
||||
},
|
||||
"Ureq transport error: Timeout occurred",
|
||||
"ureq transport error: Timeout occurred",
|
||||
),
|
||||
(
|
||||
EsploraError::Http { status_code: 404 },
|
||||
"HTTP error with status code: 404",
|
||||
"http error with status code: 404",
|
||||
),
|
||||
(
|
||||
EsploraError::Io {
|
||||
error_message: "File not found".to_string(),
|
||||
},
|
||||
"IO error: File not found",
|
||||
"io error: File not found",
|
||||
),
|
||||
(EsploraError::NoHeader, "No header found in the response"),
|
||||
(EsploraError::NoHeader, "no header found in the response"),
|
||||
(
|
||||
EsploraError::Parsing {
|
||||
error_message: "Invalid JSON".to_string(),
|
||||
},
|
||||
"Parsing error: Invalid JSON",
|
||||
"parsing error: Invalid JSON",
|
||||
),
|
||||
(
|
||||
EsploraError::BitcoinEncoding {
|
||||
error_message: "Bad format".to_string(),
|
||||
},
|
||||
"Bitcoin encoding error: Bad format",
|
||||
"bitcoin encoding error: Bad format",
|
||||
),
|
||||
(
|
||||
EsploraError::Hex {
|
||||
error_message: "Invalid hex".to_string(),
|
||||
},
|
||||
"Hex decoding error: Invalid hex",
|
||||
"hex decoding error: Invalid hex",
|
||||
),
|
||||
(EsploraError::TransactionNotFound, "Transaction not found"),
|
||||
(EsploraError::TransactionNotFound, "transaction not found"),
|
||||
(
|
||||
EsploraError::HeaderHeightNotFound { height: 123456 },
|
||||
"Header height 123456 not found",
|
||||
"header height 123456 not found",
|
||||
),
|
||||
(EsploraError::HeaderHashNotFound, "Header hash not found"),
|
||||
(EsploraError::HeaderHashNotFound, "header hash not found"),
|
||||
];
|
||||
|
||||
for (error, expected_message) in cases {
|
||||
|
Loading…
x
Reference in New Issue
Block a user