block: Add BlockError struct with Display and Error impls

Add the single public crate error type. It combines a
BlockErrorKind for classification, an optional boxed source
for the underlying cause, and an optional ErrorContext for
diagnostics. Display renders the kind and context only,
leaving source traversal to error reporters so the cause
chain is not duplicated in human readable output.

Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
This commit is contained in:
Anatol Belski
2026-03-04 22:29:54 +01:00
committed by Rob Bradford
parent 55504177cb
commit d5467dca8e

View File

@@ -16,6 +16,7 @@
//! +-- io::Error / etc.
//! ```
use std::error::Error as StdError;
use std::fmt::{self, Display, Formatter};
use std::path::PathBuf;
@@ -46,12 +47,12 @@ impl Display for BlockErrorKind {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
match self {
Self::Io => write!(f, "I/O error"),
Self::InvalidFormat => write!(f, "invalid format"),
Self::UnsupportedFeature => write!(f, "unsupported feature"),
Self::CorruptImage => write!(f, "corrupt image"),
Self::OutOfBounds => write!(f, "out of bounds"),
Self::NotFound => write!(f, "not found"),
Self::Overflow => write!(f, "overflow"),
Self::InvalidFormat => write!(f, "Invalid format"),
Self::UnsupportedFeature => write!(f, "Unsupported feature"),
Self::CorruptImage => write!(f, "Corrupt image"),
Self::OutOfBounds => write!(f, "Out of bounds"),
Self::NotFound => write!(f, "Not found"),
Self::Overflow => write!(f, "Overflow"),
}
}
}
@@ -109,3 +110,36 @@ impl Display for ErrorContext {
Ok(())
}
}
/// Unified error type for the block crate.
///
/// Pairs a stable [`BlockErrorKind`] classification with an optional
/// boxed source error (format-specific) and optional [`ErrorContext`].
///
/// Display renders kind + context only; the underlying cause is
/// exposed via [`std::error::Error::source()`] for reporters that
/// walk the chain.
#[derive(Debug)]
pub struct BlockError {
kind: BlockErrorKind,
source: Option<Box<dyn StdError + Send + Sync + 'static>>,
ctx: Option<ErrorContext>,
}
impl Display for BlockError {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.kind)?;
if let Some(ctx) = &self.ctx {
write!(f, " ({ctx})")?;
}
Ok(())
}
}
impl StdError for BlockError {
fn source(&self) -> Option<&(dyn StdError + 'static)> {
self.source
.as_ref()
.map(|e| e.as_ref() as &(dyn StdError + 'static))
}
}