Expand description
§Anyhow-Tracing
An extension of the anyhow
crate that provides named fields on an equivalent
of anyhow::Error
. Named fields are stored as a Vec<(&'static str, Box<str>)>
to allow for passing the error object around as an owned instance.
§Features
- Named Fields: Add structured key-value fields to errors for better debugging and logging.
- Drop-in Replacement: Compatible macros that work like
anyhow!
,bail!
, andensure!
. - Error Chaining: Preserves error chains while maintaining named fields, new named fields are added to the error.
- Debug and Display Fields: Support for both
Display
andDebug
formatting of field values. - Context Extension: Extends the
Context
trait to work with named fields.
§Quick Start
Add this to your Cargo.toml
:
[dependencies]
anyhow-tracing = "0.1"
§Basic Usage
use anyhow_tracing::{anyhow, bail, ensure, Context, Error, Result};
// Create errors with named fields
let err: Error = anyhow!(
user_id = "user123",
session_id = "sess456",
"Authentication failed for user"
);
// Access field values
println!("User ID: {:?}", err.get_field("user_id"));
println!("Session ID: {:?}", err.get_field("session_id"));
// Error with debug formatting
let data = vec![1, 2, 3];
let err: Error = anyhow!(data = ?data, "Processing failed");
// Using bail! macro
fn validate_input(value: i32) -> Result<()> {
if value < 0 {
bail!(
input_value = value.to_string(),
constraint = "non_negative",
"Invalid input");
}
Ok(())
}
// Using ensure! macro
fn process_number(value: i32) -> Result<i32> {
ensure!(value >= 0, value, "Number must be non-negative");
ensure!(value <= 100, value, max_allowed = "100", "Number must be at most 100");
Ok(value * 2)
}
// Error chaining with context
let result: Result<()> = Err(anyhow!(component = "postgresql", "Database error"));
let final_result = match result {
Ok(v) => Ok(v),
Err(e) => Err(e.context("User service unavailable"))
};
// Working with standard library errors
use std::fs;
let result = fs::read_to_string("/nonexistent/file")
.with_field("operation", "read_config")
.with_field("file_type", "toml");
§Context Trait Extensions
The crate extends the Context
trait to work with standard library types:
use anyhow_tracing::{Context, Result};
use std::fs::File;
// On Result types
let result: Result<File> = File::open("/nonexistent/path")
.with_field("operation", "file_open");
// On Option types
let maybe_value: Option<String> = None;
let result: Result<String> = maybe_value
.with_field("context", "parsing")
.context("Value was None");
§Compatibility
This crate is designed to be a drop-in replacement for anyhow
with additional functionality. Most anyhow
code should work with minimal changes, primarily requiring:
- Import changes:
anyhow
→anyhow_tracing
- Macro syntax: Use
,
to separate fields and messages - similar totracing::event!
. - Method chaining: Be explicit about context operations to avoid trait conflicts
§📄 License
Licensed under either of
- Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)
at your option.
§🤝 Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.
Macros§
- anyhow
- Creates an
Error
from a format string and arguments, optionally with named fields. - bail
- Returns early with an
Error
. - ensure
- Returns early with an
Error
if a condition is not satisfied.
Structs§
- Chain
- Iterator of a chain of source errors.
- Error
- An error type that extends
anyhow::Error
with named fields.
Traits§
- Context
- Extension trait for adding context and fields to errors.
Type Aliases§
- Result
- A type alias for
Result<T, Error>
.