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