Expand description
§SNAFU Virtual Stack Trace
A lightweight, efficient error handling library for Rust that implements virtual stack traces based on GreptimeDB’s error handling approach. This library combines the power of SNAFU error handling with virtual stack traces to provide meaningful error context without the overhead of system backtraces.
§Motivation
Traditional error handling in Rust often faces a dilemma:
- Option 1: Use system backtraces - long hard to read stack traces only referencing functions and lines
- Option 2: Simple error propagation - lacks context about where errors originated
Virtual stack traces provide a third way: capturing meaningful context at each error propagation point with minimal overhead.
§Features
- 🚀 Lightweight: Only ~100KB binary overhead vs several MB for system backtraces
- 📍 Precise Location Tracking: Automatically captures file, line, and column information
- 🔗 Error Chain Walking: Traverses the entire error source chain
- 🎯 Zero-Cost Abstraction: Context generation can be postponed until needed
- 🛠️ Seamless Integration: Works perfectly with SNAFU error handling
- 📝 Developer-Friendly: Automatic Debug implementation with formatted stack traces
§Basic Usage
Simply add the #[stack_trace_debug] attribute to your SNAFU error enum:
use snafu::prelude::*;
use snafu_virtstack::stack_trace_debug;
#[derive(Snafu)]
#[stack_trace_debug] // Add this attribute
enum MyError {
#[snafu(display("Failed to read file: {filename}"))]
FileRead { filename: String, source: std::io::Error },
#[snafu(display("Invalid data format"))]
InvalidFormat { source: serde_json::Error },
}
fn process_file(filename: &str) -> Result<String, MyError> {
let content = std::fs::read_to_string(filename)
.context(FileReadSnafu { filename })?;
let data: serde_json::Value = serde_json::from_str(&content)
.context(InvalidFormatSnafu)?;
Ok(data.to_string())
}§Generated Debug Output
When an error occurs, the generated Debug implementation will display:
Error: Failed to read file: config.json
Virtual Stack Trace:
0: Failed to read file: config.json at src/main.rs:15:23
1: No such file or directory (os error 2) at src/main.rs:16:10§Advanced Usage
You can also access the virtual stack programmatically:
use snafu_virtstack::VirtualStackTrace;
let error = MyError::SomethingWrong;
let stack = error.virtual_stack();
for (i, frame) in stack.iter().enumerate() {
println!("Frame {}: {} at {}:{}",
i,
frame.message,
frame.location.file(),
frame.location.line()
);
}§Requirements
- Must be applied to
enumtypes only - The enum should derive [
Snafu] for full functionality - Works best with error enums that have source fields for error chaining
§Performance Benefits
The virtual stack trace approach provides several key advantages:
§1. Performance Efficiency
Unlike system backtraces that capture the entire call stack (expensive operation), virtual stack traces only record error propagation points. This results in:
- Lower CPU usage during error handling
- Reduced memory footprint
- Smaller binary sizes (100KB vs several MB)
§2. Meaningful Context
Virtual stack traces capture:
- The exact location where each error was propagated
- Custom error messages at each level
- The complete error chain from root cause to final error
§3. Production-Ready
- Safe to use in production environments
- No performance penalties in the happy path
- Can be enabled/disabled at runtime if needed
§How It Works
-
Proc Macro Magic: The
stack_trace_debugattribute automatically implements:VirtualStackTracetrait for stack frame collection- Custom
Debugimplementation for formatted output
-
Location Tracking: Uses Rust’s
#[track_caller]to capture precise locations where errors are propagated -
Error Chain Walking: Automatically traverses the
source()chain to build complete error context -
Zero-Cost Until Needed: Stack frames are only generated when the error is actually inspected
Structs§
- Stack
Frame - Represents a single frame in the virtual stack trace.
Traits§
- Virtual
Stack Trace - Core trait for virtual stack trace functionality.
Attribute Macros§
- stack_
trace_ debug - Proc macro attribute to automatically generate virtual stack traces for SNAFU errors.