Expand description
§Errors
This module defines globally shared error messages, the crate-level error wrapper and extension traits for error/results. Our error paradigm is as follows:
- Modules define their own error types when they need shared error messages. Module-level errors can wrap eyre::Report to capture arbitrary errors.
- The crate-level error wrapper (BridgeError) is used to wrap errors from modules and attach extra context (ie. which module caused the error).
- External crate errors are always wrapped by the BridgeError and never by module-level errors.
- When using external crates inside modules, extension traits are used to convert external-crate errors into BridgeError. This is further wrapped in an eyre::Report to avoid a circular dependency.
- BridgeError can be converted to tonic::Status to be returned to the client. Module-level errors can define Into
to customize the returned status. - BridgeError can be used to share error messages across modules.
- When the error cause is not sufficiently explained by the error messages, use
eyre::Context::wrap_err
to add more context. This will not hinder modules that are trying to match the error.
§Error wrapper example usage with TxError
use thiserror::Error;
use clementine_core::errors::{BridgeError, TxError, ErrorExt, ResultExt};
// Function with external crate signature
pub fn external_crate() -> Result<(), hex::FromHexError> {
Err(hex::FromHexError::InvalidStringLength)
}
// Internal function failing with some error
pub fn internal_function_in_another_module() -> Result<(), BridgeError> {
Err(eyre::eyre!("I just failed").into())
}
// This function returns module-level errors
// It can wrap external crate errors, and other crate-level errors
pub fn create_some_txs() -> Result<(), TxError> {
// Do external things
// This wraps the external crate error with BridgeError, then boxes inside an eyre::Report. The `?` will convert the eyre::Report into a TxError.
external_crate().map_to_eyre()?;
// Do internal things
// This will simply wrap in eyre::Report, then rewrap in TxError.
internal_function_in_another_module().map_to_eyre()?;
// Return a module-level error
Err(TxError::TxInputNotFound)
}
pub fn test() -> Result<(), BridgeError> {
create_some_txs()?;
// This will convert the TxError into a BridgeError, wrapping the error with the message "Failed to build transactions" regardless of the actual error.
// Chain will be:
// 1. External case: BridgeError -> TxError -> eyre::Report -> hex::FromHexError
// 2. Internal case: BridgeError -> TxError -> eyre::Report -> BridgeError -> eyre::Report (this could've been any other module-level error)
// 3. Module-level error: BridgeError -> TxError
// error(transparent) ensures that unnecessary error messages are not repeated.
Ok(())
}
pub fn main() {
assert!(test().is_err());
}
Re-exports§
pub use crate::builder::transaction::TxError;
Enums§
- Errors returned by the bridge.
Traits§
- Extension traits for errors to easily convert them to eyre::Report and tonic::Status through BridgeError.
- Extension traits for results to easily convert them to eyre::Report and tonic::Status through BridgeError.