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;