Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add thiserror for better display error formatting #813

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ bitcoin = { version = "0.29.1", features = ["serde", "base64", "rand"] }
serde = { version = "^1.0", features = ["derive"] }
serde_json = { version = "^1.0" }
rand = "^0.8"
thiserror = "^1.0"

# Optional dependencies
sled = { version = "0.34", optional = true }
Expand Down
42 changes: 22 additions & 20 deletions src/blockchain/compact_filters/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@
//! ```

use std::collections::HashSet;
use std::fmt;
use std::path::Path;
use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::{Arc, Mutex};
Expand Down Expand Up @@ -534,61 +533,64 @@ impl ConfigurableBlockchain for CompactFiltersBlockchain {
}

/// An error that can occur during sync with a [`CompactFiltersBlockchain`]
#[derive(Debug)]
#[derive(Debug, thiserror::Error)]
pub enum CompactFiltersError {
/// A peer sent an invalid or unexpected response
#[error("A peer sent an invalid or unexpected response")]
InvalidResponse,
/// The headers returned are invalid
#[error("Invalid headers")]
InvalidHeaders,
/// The compact filter headers returned are invalid
#[error("Invalid filter header")]
InvalidFilterHeader,
/// The compact filter returned is invalid
#[error("Invalid filters")]
InvalidFilter,
/// The peer is missing a block in the valid chain
#[error("The peer is missing a block in the valid chain")]
MissingBlock,
/// Block hash at specified height not found
#[error("Block hash not found")]
BlockHashNotFound,
/// The data stored in the block filters storage are corrupted
#[error("The data stored in the block filters storage are corrupted")]
DataCorruption,

/// A peer is not connected
#[error("A peer is not connected")]
NotConnected,
/// A peer took too long to reply to one of our messages
#[error("A peer took too long to reply to one of our messages")]
Timeout,
/// The peer doesn't advertise the [`BLOOM`](bitcoin::network::constants::ServiceFlags::BLOOM) service flag
#[error("Peer doesn't advertise the BLOOM service flag")]
PeerBloomDisabled,

/// No peers have been specified
#[error("No peers have been specified")]
NoPeers,

/// Internal database error
Db(rocksdb::Error),
#[error("Internal database error: {0}")]
Db(#[from] rocksdb::Error),
/// Internal I/O error
Io(std::io::Error),
#[error("Internal I/O error: {0}")]
Io(#[from] std::io::Error),
/// Invalid BIP158 filter
Bip158(bitcoin::util::bip158::Error),
#[error("Invalid BIP158 filter: {0}")]
Bip158(#[from] bitcoin::util::bip158::Error),
/// Internal system time error
Time(std::time::SystemTimeError),
#[error("Invalid system time: {0}")]
Time(#[from] std::time::SystemTimeError),

/// Wrapper for [`crate::error::Error`]
#[error("Generic error: {0}")]
Global(Box<crate::error::Error>),
}

impl fmt::Display for CompactFiltersError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{:?}", self)
}
}

impl std::error::Error for CompactFiltersError {}

impl_error!(rocksdb::Error, Db, CompactFiltersError);
impl_error!(std::io::Error, Io, CompactFiltersError);
impl_error!(bitcoin::util::bip158::Error, Bip158, CompactFiltersError);
impl_error!(std::time::SystemTimeError, Time, CompactFiltersError);

impl From<crate::error::Error> for CompactFiltersError {
fn from(err: crate::error::Error) -> Self {
CompactFiltersError::Global(Box::new(err))
Self::Global(Box::new(err))
}
}
42 changes: 19 additions & 23 deletions src/descriptor/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,56 +12,52 @@
//! Descriptor errors

/// Errors related to the parsing and usage of descriptors
#[derive(Debug)]
#[derive(Debug, thiserror::Error)]
pub enum Error {
/// Invalid HD Key path, such as having a wildcard but a length != 1
#[error("Invalid HD key path")]
InvalidHdKeyPath,
/// The provided descriptor doesn't match its checksum
#[error("The provided descriptor doesn't match its checksum")]
InvalidDescriptorChecksum,
/// The descriptor contains hardened derivation steps on public extended keys
#[error("The descriptor contains hardened derivation steps on public extended keys")]
HardenedDerivationXpub,

/// Error thrown while working with [`keys`](crate::keys)
#[error("Key error: {0}")]
Key(crate::keys::KeyError),
/// Error while extracting and manipulating policies
Policy(crate::descriptor::policy::PolicyError),
#[error("Policy error: {0}")]
Policy(#[from] crate::descriptor::policy::PolicyError),

/// Invalid byte found in the descriptor checksum
#[error("Invalid descriptor character: {0}")]
InvalidDescriptorCharacter(u8),

/// BIP32 error
Bip32(bitcoin::util::bip32::Error),
#[error("BIP32 error: {0}")]
Bip32(#[from] bitcoin::util::bip32::Error),
/// Error during base58 decoding
Base58(bitcoin::util::base58::Error),
#[error("Base58 error: {0}")]
Base58(#[from] bitcoin::util::base58::Error),
/// Key-related error
Pk(bitcoin::util::key::Error),
#[error("Key-related error: {0}")]
Pk(#[from] bitcoin::util::key::Error),
/// Miniscript error
Miniscript(miniscript::Error),
#[error("Miniscript error: {0}")]
Miniscript(#[from] miniscript::Error),
/// Hex decoding error
Hex(bitcoin::hashes::hex::Error),
#[error("Hex decoding error: {0}")]
Hex(#[from] bitcoin::hashes::hex::Error),
}

impl From<crate::keys::KeyError> for Error {
fn from(key_error: crate::keys::KeyError) -> Error {
match key_error {
crate::keys::KeyError::Miniscript(inner) => Error::Miniscript(inner),
crate::keys::KeyError::Bip32(inner) => Error::Bip32(inner),
e => Error::Key(e),
e => Self::Key(e),
}
}
}

impl std::fmt::Display for Error {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{:?}", self)
}
}

impl std::error::Error for Error {}

impl_error!(bitcoin::util::bip32::Error, Bip32);
impl_error!(bitcoin::util::base58::Error, Base58);
impl_error!(bitcoin::util::key::Error, Pk);
impl_error!(miniscript::Error, Miniscript);
impl_error!(bitcoin::hashes::hex::Error, Hex);
impl_error!(crate::descriptor::policy::PolicyError, Policy);
17 changes: 7 additions & 10 deletions src/descriptor/policy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@

use std::cmp::max;
use std::collections::{BTreeMap, HashSet, VecDeque};
use std::fmt;

use serde::ser::SerializeMap;
use serde::{Serialize, Serializer};
Expand Down Expand Up @@ -494,30 +493,28 @@ impl Condition {
}

/// Errors that can happen while extracting and manipulating policies
#[derive(Debug, PartialEq, Eq)]
#[derive(Debug, PartialEq, Eq, thiserror::Error)]
pub enum PolicyError {
/// Not enough items are selected to satisfy a [`SatisfiableItem::Thresh`] or a [`SatisfiableItem::Multisig`]
#[error("Not enought items selected: {0}")]
NotEnoughItemsSelected(String),
/// Index out of range for an item to satisfy a [`SatisfiableItem::Thresh`] or a [`SatisfiableItem::Multisig`]
#[error("Index out of range: {0}")]
IndexOutOfRange(usize),
/// Can not add to an item that is [`Satisfaction::None`] or [`Satisfaction::Complete`]
#[error("Add on leaf")]
AddOnLeaf,
/// Can not add to an item that is [`Satisfaction::PartialComplete`]
#[error("Add on partial complete")]
AddOnPartialComplete,
/// Can not merge CSV or timelock values unless both are less than or both are equal or greater than 500_000_000
#[error("Mixed timelock units")]
MixedTimelockUnits,
/// Incompatible conditions (not currently used)
#[error("Incompatible conditions")]
IncompatibleConditions,
}

impl fmt::Display for PolicyError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{:?}", self)
}
}

impl std::error::Error for PolicyError {}

impl Policy {
fn new(item: SatisfiableItem) -> Self {
Policy {
Expand Down
Loading