charon_error/lib.rs
1#![forbid(unsafe_code)]
2#![deny(clippy::all)]
3//! # Charon Error
4//!
5//! Structured error handling for Rust with rich error reports, data sensitivity
6//! labels, panic capture, and GitLab issue integration.
7//!
8//! Named after Charon, the Greek ferryman of the dead across the river Styx —
9//! this crate ferries your program from a running state to a graceful death,
10//! collecting every detail along the way.
11//!
12//! ## Features
13//!
14//! - **Error chains**: Stack multiple errors with [`ErrorReport`] to preserve full context
15//! - **Sensitivity labels**: Tag data as [`Public`](ErrorSensitivityLabel::Public),
16//! [`Private`](ErrorSensitivityLabel::Private), [`Internal`](ErrorSensitivityLabel::Internal),
17//! or [`Confidential`](ErrorSensitivityLabel::Confidential) to control what gets shared
18//! - **Panic hooks**: Capture panics and display human-readable reports with
19//! [`setup_panic!`] and [`setup_panic_simple!`]
20//! - **Issue submission**: Generate pre-filled GitLab issue URLs from errors via
21//! [`GitLabErrorReport`]
22//! - **Tracing integration**: Works with the `tracing` crate - use `#[instrument]`
23//! and `tracing::error!()` alongside `ErrorReport`
24//! - **Flexible formatting**: Configure output detail with [`ErrorFmtSettings`]
25//!
26//! ## Quick Start
27//!
28//! ```rust,no_run
29//! use charon_error::prelude::*;
30//!
31//! #[derive(Debug, ThisError)]
32//! enum AppError {
33//! #[error("failed to load config")]
34//! ConfigLoad,
35//! }
36//!
37//! fn load_config() -> ResultER<String> {
38//! std::fs::read_to_string("config.toml")
39//! .change_context(AppError::ConfigLoad)?;
40//! Ok("loaded".to_owned())
41//! }
42//! ```
43//!
44//! ## Using `ResultER<T>`
45//!
46//! [`ResultER<T>`] is a type alias for `Result<T, ErrorReport>`. Use it as your
47//! return type and the [`ResultExt`] trait methods become available on any
48//! `Result` or `Option`:
49//!
50//! ```rust,no_run
51//! use charon_error::prelude::*;
52//!
53//! fn example() -> ResultER<()> {
54//! let value: i32 = "not_a_number"
55//! .parse::<i32>()
56//! .change_context(StringError::new("parsing failed"))?;
57//! Ok(())
58//! }
59//! ```
60
61mod errors;
62#[macro_use]
63mod panic_hook;
64mod error_formating;
65/// Prelude module for convenient imports.
66///
67/// Import everything with `use charon_error::prelude::*;`
68pub mod prelude;
69mod report;
70mod result_ext;
71mod submit;
72mod utils;
73
74pub use error_formating::*;
75pub use errors::*;
76pub use report::{ErrorAttachment, ErrorFrame, ErrorReport, ErrorSensitivityLabel};
77pub use result_ext::ResultExt;
78pub use submit::{GitLabERGlobalSettings, GitLabErrorReport, SubmitErrorReport};
79pub use utils::{LinkDebugIde, SourceLocation};
80
81/// Convenience type alias for `Result<T, ErrorReport>`.
82///
83/// ER stands for ErrorReport. Use this as the return type for functions
84/// that can fail with structured error reports.
85///
86/// # Example
87///
88/// ```rust,no_run
89/// use charon_error::prelude::*;
90///
91/// fn do_work() -> ResultER<String> {
92/// Ok("done".to_owned())
93/// }
94/// ```
95pub type ResultER<T> = Result<T, ErrorReport>;