Crate snafu_virtstack

Crate snafu_virtstack 

Source
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 enum types 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

  1. Proc Macro Magic: The stack_trace_debug attribute automatically implements:

  2. Location Tracking: Uses Rust’s #[track_caller] to capture precise locations where errors are propagated

  3. Error Chain Walking: Automatically traverses the source() chain to build complete error context

  4. Zero-Cost Until Needed: Stack frames are only generated when the error is actually inspected

Structs§

StackFrame
Represents a single frame in the virtual stack trace.

Traits§

VirtualStackTrace
Core trait for virtual stack trace functionality.

Attribute Macros§

stack_trace_debug
Proc macro attribute to automatically generate virtual stack traces for SNAFU errors.