diidi_travel_common_error/lib.rs
1//! Shared error layer for the DiiDi Travel monorepo.
2//!
3//! Every service throws the same [`AppError`] — categorized, code-stable, context-rich, and
4//! source-chained. Cross-cutting concerns (HTTP status, gRPC status, JSON wire shape, severity ↔
5//! tracing-level mapping) live here so each service doesn't reinvent them.
6//!
7//! ## Quick start
8//! ```no_run
9//! use diidi_travel_common_error::{AppError, ErrorCategory, Result, ResultExt, bail, ensure};
10//!
11//! fn lookup(id: u64) -> Result<&'static str> {
12//! ensure!(id != 0, ErrorCategory::Validation, "user.id.invalid", "id must be > 0");
13//! if id == 1 {
14//! return Ok("alice");
15//! }
16//! bail!(ErrorCategory::NotFound, "user.not_found", "no user with id {id}");
17//! }
18//!
19//! fn handle() -> Result<()> {
20//! let _name = lookup(0).err_context("operation", "handle")?;
21//! Ok(())
22//! }
23//! ```
24//!
25//! ## Shape
26//! - [`AppError`] — main type
27//! - [`ErrorCategory`] — broad classification with HTTP/gRPC mapping
28//! - [`ErrorCode`] — stable, machine-readable identifier
29//! - [`ErrorContext`] — open-ended key/value metadata
30//! - [`Severity`] — used for logging routing
31//! - [`ErrorResponse`] — wire shape for replying to callers
32//! - [`Result`] — `std::result::Result<T, AppError>` alias
33//! - [`ResultExt`] — fluent error decoration on `Result`
34//! - macros: [`app_error!`], [`bail!`], [`ensure!`]
35
36pub mod category;
37pub mod code;
38pub mod context;
39pub mod error;
40pub mod macros;
41pub mod response;
42pub mod result;
43pub mod severity;
44
45pub use crate::category::{ErrorCategory, UnknownCategory};
46pub use crate::code::{ErrorCode, UNSPECIFIED};
47pub use crate::context::ErrorContext;
48pub use crate::error::{AppError, BoxedStdError};
49pub use crate::response::ErrorResponse;
50pub use crate::result::{Result, ResultExt};
51pub use crate::severity::Severity;