Skip to main content

rtb_error/
lib.rs

1//! Error types and the diagnostic-report pipeline.
2//!
3//! The framework follows the `thiserror` + `miette` pattern:
4//!
5//! * Library-level crates define typed errors with
6//!   `#[derive(thiserror::Error, miette::Diagnostic)]`.
7//! * At the process boundary (`fn main() -> miette::Result<()>`), errors
8//!   are rendered by a `miette` hook installed via [`hook`].
9//! * There is **no** `ErrorHandler` trait or `.check()` funnel — errors
10//!   are values, propagated with `?`, and reported once at the edge.
11//!
12//! See `docs/development/specs/2026-04-22-rtb-error-v0.1.md` for the
13//! authoritative contract.
14
15#![forbid(unsafe_code)]
16
17pub use miette::{Diagnostic, Report};
18
19use thiserror::Error;
20
21/// Canonical framework result alias.
22pub type Result<T, E = Error> = std::result::Result<T, E>;
23
24/// Umbrella error enum for the framework.
25///
26/// Downstream crates should define their own `#[derive(Error, Diagnostic)]`
27/// enums and convert at the boundary. This enum captures only the errors
28/// raised by the application scaffolding itself, plus the [`Error::Other`]
29/// escape hatch for downstream typed diagnostics.
30#[derive(Debug, Error, Diagnostic)]
31#[non_exhaustive]
32pub enum Error {
33    /// Configuration source rejected the value.
34    #[error("configuration error: {0}")]
35    #[diagnostic(code(rtb::config))]
36    Config(String),
37
38    /// Filesystem or network I/O.
39    #[error("I/O error: {0}")]
40    #[diagnostic(code(rtb::io))]
41    Io(#[from] std::io::Error),
42
43    /// No registered command matches the user-supplied name.
44    #[error("command not found: {0}")]
45    #[diagnostic(code(rtb::command_not_found), help("run `--help` to list available commands"))]
46    CommandNotFound(String),
47
48    /// A built-in command was requested but its Cargo feature is off.
49    #[error("feature `{0}` is not compiled in")]
50    #[diagnostic(
51        code(rtb::feature_disabled),
52        help("rebuild with the appropriate Cargo feature enabled")
53    )]
54    FeatureDisabled(&'static str),
55
56    /// A downstream crate's typed diagnostic, kept live for rendering.
57    #[error("{0}")]
58    #[diagnostic(transparent)]
59    Other(#[from] Box<dyn Diagnostic + Send + Sync + 'static>),
60}
61
62pub mod hook;