rtb-error¶
rtb-error is the error-handling foundation of the phpboyscout Rust toolkit.
It gives you four things:
- an umbrella
Errorenum for application scaffolding failures, and theResult<T, E = Error>alias; - a
hookmodule that installs a graphical diagnostic renderer, a matching panic hook, and a support footer you can change at any time; - exit-code attachment, so a specific error can set a specific process exit code;
- a position on how errors should travel:
as values, propagated with
?, rendered once at the edge.
Everything is built on miette and thiserror. If you
already use those directly, rtb-error adds types and a hook wrapper, not
capability — see
what it does not do before adopting
it.
Part of the phpboyscout Rust toolkit; extracted from — and still consumed by — rust-tool-base.
Install it¶
miette and thiserror are separate because you need their derive macros in
your own crate. rtb-error re-exports the Diagnostic trait and derive, but
not thiserror::Error.
What it looks like¶
use std::process::ExitCode;
use rtb_error::exit_code_of;
fn main() -> ExitCode {
rtb_error::hook::install_with_footer(|| {
"Report bugs at https://example.invalid/greet/issues".to_string()
});
rtb_error::hook::install_panic_hook();
match run() {
Ok(()) => ExitCode::SUCCESS,
Err(report) => {
eprintln!("Error: {report:?}");
ExitCode::from(exit_code_of(&report).unwrap_or(1))
}
}
}
Error: greet::no_name
x no name given
help: pass a name: `greet Ada`
Report bugs at https://example.invalid/greet/issues
Where to start¶
| If you want to… | Go to |
|---|---|
| Build one of these from an empty project | Tutorial: give your CLI a diagnostic error path |
| Do one specific thing — install the pipeline, set an exit code, add a footer | How-to guides |
| Look up a variant, a diagnostic code, a default or a failure mode | Reference |
| Understand why there is no error-handler object | Explanation |
| Read the generated API docs | docs.rs/rtb-error |
The one thing to get right¶
miette's renderer lives in a process-global slot that can only be written
once, and it is filled by whichever comes first: your install_* call, or the
construction of the first miette::Report anywhere in the process. Install too
late and this crate's handler never runs, the footer never appears, and nothing
warns you.
Put the install calls at the very top of main, before any fallible work. The
mechanism is explained in
Why the hook is installed once.
What this does not do¶
It does not log, does not decide your exit code for you, does not redact
anything, and does not adapt rendering to the terminal the way miette's own
default handler does. There are no Cargo features and no no_std build. The
full list, with the workaround for each, is
What rtb-error does not do.
Which crates use it¶
| Crate | How it uses rtb-error |
|---|---|
rtb-cli 0.9.0 |
Installs all three hooks in Application::run_with_args when hooks are enabled, sourcing the footer from ToolMetadata::help; raises Error::CommandNotFound on an unknown subcommand; maps a report to a process exit code with exit_code_of(report).unwrap_or(1); re-exports Error and Result from its prelude as RtbError and RtbResult |
rtb-app 0.9.0 |
Declares the dependency and defines the HelpChannel that rtb-cli turns into the footer text |
rtb-config, rtb-credentials and rtb-telemetry do not depend on
rtb-error in their currently published versions, despite what older
descriptions of the toolkit said.
None of these crates are required to use rtb-error. It has no dependency on
any of them and works in a plain cargo new binary — which is what the
tutorial builds.