[Go to site: main page, start]

Skip to content

rtb-error

rtb-error is the error-handling foundation of the phpboyscout Rust toolkit. It gives you four things:

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

$ cargo add rtb-error miette thiserror

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.