orion-error
Structured error governance for large Rust codebases.
orion-error is not just an error type library.
It is a governance framework for large Rust services and multi-layer systems. It helps teams move from ad-hoc strings and mixed local conventions to one shared error model for:
- semantic modeling
- runtime propagation
- context attachment
- cross-layer conversion
- boundary-facing output for HTTP / RPC / CLI / logs
Core building blocks:
- stable business identities via
#[derive(OrionError)] - one runtime carrier:
StructError<R> - explicit first-entry conversion with
into_as(...) - explicit cross-layer wrapping with
wrap_as(...) - report, snapshot, and exposure helpers for service boundaries
Why It Is Useful
Use this crate when you want:
- one shared error language across service / repo / adapter / protocol layers
- clear business error enums instead of scattered strings
- one consistent way to attach detail, source, and operation context
- stable machine-facing identity for HTTP / RPC / log / CLI boundaries
- controlled bridging to
std::error::Erroronly where needed - a system that scales better than local
Result<T, String>habits
If you only need a tiny local enum inside one module, thiserror alone may be
enough. If your service has layers, external boundaries, and structured error
output, orion-error is the better fit.
In short:
thiserroris a good local modeling toolorion-erroris for project-wide error governance
Install
[]
= "0.7"
Default features include derive and log.
Common optional features:
[]
= { = "0.7", = ["serde"] }
= { = "0.7", = ["serde_json"] }
= { = "0.7", = ["tracing"] }
= { = "0.7", = ["anyhow"] }
= { = "0.7", = ["toml"] }
Quick Start
use From;
use ;
What happens here:
AppReasonis your domain reason enumStructError<AppReason>is the runtime error carrierinto_as(...)converts a normal Rust error into the structured systemdoing(...)andwith_context(...)add operation context
For new code, treat doing(...) as the standard operation verb. want(...)
only exists as a compatibility path for older code.
The 4 APIs To Learn First
#[derive(OrionError)]Define stable business-facing reason enums.into_as(reason, detail)Use when a plain error enters the structured system for the first time.err_conv()Use when the upstream value is alreadyStructError<R1>and you only remap reason type toStructError<R2>.wrap_as(reason, detail)Use when the upstream value is alreadyStructError<_>and the upper layer wants a new semantic boundary.
Typical Flow
std::io::Error
-> into_as(...)
StructError<RepoReason>
-> err_conv() or wrap_as(...)
StructError<ServiceReason>
-> report() / snapshot().stable_export() / exposure_snapshot(...)
This is the important shift:
- lower layers do not invent random output shapes
- middle layers do not lose source and context
- boundary layers do not re-interpret raw strings
- the whole system shares one governance model
Service Boundary Helpers
When you reach HTTP/RPC/log/CLI boundaries, these are the main entry points:
report()for human-oriented diagnosticssnapshot().stable_export()for stable machine exportexposure_snapshot(...)withto_http_error_json(),to_cli_error_json(),to_log_error_json(),to_rpc_error_json()
Current protocol naming is Exposure*, not ErrorPolicy*.
That matters because large systems usually fail at the boundary:
- one team exposes too much detail
- another team hides everything
- every protocol builds its own error schema
orion-error gives those boundaries one consistent projection model.
Standard Error Bridge
StructError<R> no longer directly implements std::error::Error.
Use the explicit bridge APIs when you need that ecosystem:
let borrowed_std = err.as_std;
let owned_std = err.clone.into_std;
let boxed_std = err.into_boxed_std;
Recommended Imports
For new code, start with:
use *;
Then add only the layered imports you need, for example:
orion_error::reason::UvsReasonorion_error::runtime::OperationContextorion_error::report::*orion_error::snapshot::*
This keeps application code simple while still letting larger codebases keep clear module boundaries.
Try It
Learn More
- 中文 README
- Changelog
- Docs Index
- Tutorial
- Reason Identity Guide
- Protocol Contract
- Stable Snapshot Schema
- thiserror Comparison
- orion-error-derive README
Maintainers
If publishing this crate family:
- publish
orion-error-derive - wait for crates.io index propagation
- publish
orion-error