1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
// Copyright 2024-2026 Jonathan Shook
// SPDX-License-Identifier: Apache-2.0
//! # nmbrs-errorhandler
//!
//! Contract & axioms: [SRD 07](../../docs/SRD/07_error_routing.md).
//!
//! Modular composable error handler. Errors are classified by
//! type name (regex) and routed through a chain of handlers that
//! can log, count, meter, retry, or stop execution.
//!
//! Designed for nmbrs's op-dispatch loop, where every adapter op
//! result might be `Ok` or one of dozens of named error variants
//! — and operators want different policies for different error
//! families (retry timeouts, count + ignore `WriteFailures`,
//! stop on `BadCredentials`).
//!
//! ## Pieces
//!
//! - [`ErrorDetail`] is the structured error a producer hands
//! in. Carries a name (used for routing), a retryable flag,
//! and an optional result code.
//! - [`ErrorHandler`] is the trait every leaf handler implements
//! (`StopHandler`, `WarnHandler`, `RetryHandler`,
//! `CounterHandler`, …). Each one decides how to react to the
//! incoming detail and may flip `retryable` or `stop` flags on it.
//! - [`ErrorRouter`] holds a list of `(regex, handler chain)`
//! entries and dispatches each incoming detail to the first
//! matching chain.
//!
//! ## Config syntax
//!
//! Routes are declared as semicolon-separated `pattern:chain`
//! pairs. Inside a chain, `,` separates handler names:
//!
//! ```text
//! "TimeoutError:retry,warn,counter;.*:stop"
//! ```
//!
//! Reads as: a `TimeoutError` retries (and warns + counts on
//! each attempt); anything else stops the run.
//!
//! ```
//! use nmbrs_errorhandler::ErrorRouter;
//!
//! let router = ErrorRouter::parse(
//! "TimeoutError:retry,warn,counter;.*:stop",
//! ).expect("config parses");
//! # drop(router); // exercised by integration tests in nmbrs/tests/
//! ```
//!
//! ## Building details
//!
//! [`ErrorDetail`] uses a builder-style API:
//!
//! ```
//! use nmbrs_errorhandler::ErrorDetail;
//!
//! let d = ErrorDetail::retryable("TimeoutError")
//! .with_result_code(503);
//! assert!(d.is_retryable());
//! assert_eq!(d.name, "TimeoutError");
//! ```
//!
//! ## Defaults
//!
//! For tests and one-line setups:
//!
//! - [`ErrorRouter::default_stop`] — stop on any error.
//! - [`ErrorRouter::default_warn_count`] — warn + count on any
//! error, never stop. Convenient for diagnostic runs.
pub use ;
pub use ErrorHandler;
pub use ErrorRouter;