Enhance Rust errors with file and line details using the `#[wherr]` macro for clearer debugging.

Overview

wherr Crate

version documentation License

Discuss wherr on Hacker News

Enhance Rust's ? operator by appending file and line number details to errors, simplifying the debugging process.

Features

  • 📁 Appends file and line number to errors propagated with ?.
  • 🧩 Integrates seamlessly with Rust's existing error handling.
  • 📍 Helps locate and fix errors faster by pinpointing their origin.
  • 🚀 Supports anyhow error handling through the anyhow feature flag.

Why wherr?

When using the ? operator in Rust, errors propagated don't usually provide file and line number details about where the error occurs. Especially in nested function calls with multiple potential error points, this absence of detailed info can be a debugging headache.

wherr remedies this, giving you precise location data for your errors.

Installation

Add the following to your Cargo.toml:

[dependencies]
wherr = "0.1"

For anyhow support:

[dependencies]
wherr = { version = "0.1", features = ["anyhow"] }

Quick Start

By simply annotating your functions with #[wherr], errors propagated using ? will also include the file and line number.

  1. Standard Usage: Annotate functions with #[wherr].
use wherr::wherr;

#[wherr]
fn concat_files(path1: &str, path2: &str) -> Result<String, Box<dyn std::error::Error>> {
    let mut content1 = std::fs::read_to_string(path1)?;
    let content2 = std::fs::read_to_string(path2)?;

    content1.push_str(&content2);
    Ok(content1)
}

Run the provided example:

cargo run --example with_wherr

This will highlight the difference wherr makes. Your error will now indicate exactly where the issue arises:

error at wherr/examples/with_wherr.rs:5
  1. With anyhow:

Ensure you've added the anyhow feature as shown in the installation section. Then:

use anyhow::{Context, Result};
use wherr::wherr;

#[wherr]
fn concat_files(path1: &str, path2: &str) -> Result<String> {
    let mut content1 = std::fs::read_to_string(path1).with_context(|| format!("Failed to read {}", path1))?;
    let content2 = std::fs::read_to_string(path2).with_context(|| format!("Failed to read {}", path2))?;

    content1.push_str(&content2);
    Ok(content1)
}

Run the provided example:

cargo run --features=anyhow --example anyhow

This will highlight the difference wherr makes. Your error will now indicate exactly where the issue arises:

error at wherr/examples/anyhow.rs:6

Behind the Scenes

The #[wherr] notation is a proc_macro_attribute, which allows for code transformations at compile time.

When an error is propagated using the ? operator inside a #[wherr] annotated function, the macro captures the file and line number where the error occurred.

Essentially, the function:

#[wherr]
fn add(s1: &str, s2: &str) -> Result<i64, Box<dyn std::error::Error>> {
    ...
    let i1 = i64::from_str_radix(s1, radix)?;
    ...
}

... is transformed to:

fn add(s1: &str, s2: &str) -> Result<i64, Box<dyn std::error::Error>> {
    ...
    let i1 = wherr::wherrapper(i64::from_str_radix(s1, radix), file!(), line!())?;
    ...
}

The magic happens inside wherrapper. It checks the given result, and if it's an error, wraps it with file and line details.

Usage & Examples

Dive deeper into the problem wherr solves and the Rust concepts involved with our detailed examples.

Note on Crate Organization

wherr is divided into two separate crates because of Rust's restriction against mixing normal functions and procedural macros in the same crate:

  1. wherr: This is the main library that offers the enhanced functionality for error handling in Rust.
  2. wherr-macro: Contains the procedural macros specifically designed for the wherr crate.

Contributing

If you're interested in contributing to wherr, please follow standard Rust community guidelines and submit a PR on our repository.

License

This project is dual licensed under MIT License and Apache License.

You might also like...
Single File Assets is a file storage format for images

SFA (Rust) Single File Assets is a file storage format for images. The packed images are not guaranteed to be of same format because the format while

A tool for determining file types, an alternative to file

file-rs a tool for determining file types, an alternative to file whats done determining file extension determining file type determining file's mime

SAORI for UKAGAKA. Convert a image file to resized png file.

Resized Png GitHub repository これは何? デスクトップマスコット、「伺か」で使用できるSAORIの一種です。 機能としては、指定した画像ファイルを拡大または縮小し、pngとして出力します。 「伺か」「SAORI」等の用語については詳しく説明いたしませんのでご了承下さい。

FileSorterX is an automatic file sorting application that sorts your files into folders based on their file extension
FileSorterX is an automatic file sorting application that sorts your files into folders based on their file extension

FileSorterX is an automatic file sorting application that sorts your files into folders based on their file extension. With FileSorterX, you can easily keep your files organized and find what you need quickly.

A simple command line program to upload file or directory to web3.storage with optional encryption and compression
A simple command line program to upload file or directory to web3.storage with optional encryption and compression

w3s-cli A simple command line program to upload file or directory to web3.storage with optional encryption and compression. Features Uploads single fi

rpsc is a *nix command line tool to quickly search for file systems items matching varied criterions like permissions, extended attributes and much more.

rpsc rpsc is a *nix command line tool to quickly search for file systems items matching varied criterions like permissions, extended attributes and mu

Save image from your clipboard 📋 as an image file directly from your command line! 🔥

Clpy 📋 Save copied image from clipboard as an image file directly from your command line! Note It works only on windows as of now. I'll be adding sup

Command line tool to convert env variables beginning with user to a htpasswd file

envhtp This command line tool converts environment variables whose keys start with "user_" into htpasswd compatible username/password pairs. The goal

A command line tool for easily generating multiple versions of a configuration file from a single template

MultiConf A command line tool for easily generating multiple versions of a configuration file from a single template. Why? I'm a big fan of the i3 win

Comments
  • Use of Box<dyn Error> prevents Wherr from working with anyhow

    Use of Box prevents Wherr from working with anyhow

    Being able to work with the anyhow crate would make this crate much more ergonomic for use in existing code. Currently, wherr uses Box<dyn Error> as it's inner error type and error returned from wherrapper. This is not Sized, Send, or Sync, meaning it cannot be converted into anyhow's Error type. Based on some testing I've done locally, the API of anyhow::Error is similar enough to that of Box that there would be nearly no code changes necessary between the two implementations.

    I'd like to propose the existence of a feature flag which would switch wherr to use anyhow::Error as its inner error type. This could either change the behavior of the #[wherr] macro directly, or enable the existence of a #[wherr_anyhow] macro, whichever seems most convenient (though I lean toward the former).

    If this is something you're interested in, I'd be happy to submit a PR implementing these changes.

    opened by smsutherland 4
Revolutionize handheld gaming with adaptive game settings. Optimize graphics and gameplay experience based on real-time system metrics. Open-source project empowering developers to enhance games on portable devices

Welcome to the server-side application for the HarmonyLink project. This innovative software is developed with the Rust programming language and is ai

Jordon Brooks 5 Jun 28, 2023
A standalone Command Line Interface debugging tool for The Witcher 3 written in Rust

A standalone Command Line Interface debugging tool for The Witcher 3 written in Rust. This tool is intended for Witcher 3 modders who make mainly scri

Przemysław Cedro 5 Apr 20, 2022
Detects whether a terminal supports color, and gives details about that support

Detects whether a terminal supports color, and gives details about that support. It takes into account the NO_COLOR environment variable. This crate i

Kat Marchán 30 Dec 29, 2022
Warp is a blazingly fast, Rust-based terminal that makes you and your team more productive at running, debugging, and deploying code and infrastructure.

Warp is a blazingly fast, Rust-based terminal that makes you and your team more productive at running, debugging, and deploying code and infrastructure.

Warp 10.4k Jan 4, 2023
argmax is a library that allows Rust applications to avoid Argument list too long errors (E2BIG) by providing a std::process::Command wrapper with a

argmax argmax is a library that allows Rust applications to avoid Argument list too long errors (E2BIG) by providing a std::process::Command wrapper w

David Peter 22 Nov 20, 2022
Use your computer as a cosmic ray detector! One of the memory errors Rust does not protect against.

Your computer can double up as a cosmic ray detector. Yes, really! Cosmic rays hit your computer all the time. If they hit the RAM, this can sometimes

Johanna Sörngård 110 Jun 16, 2023
A command-line tool aiming to upload the local image used in your markdown file to the GitHub repo and replace the local file path with the returned URL.

Pup A command line tool aiming to upload the local image used in your markdown file to the GitHub repo and replace the local file path with the return

SteveLau 11 Aug 17, 2022
JiaShiwen 12 Nov 5, 2022
An attribute macro to simplify writing simple command line applications.

fncli An attribute macro to simplify writing simple command line applications. Example #[fncli::cli] fn main(a: i32, b: i32) { println!("{}", a +

Vidhan Bhatt 29 Dec 15, 2022
Semantic find-and-replace using tree-sitter-based macro expansion

Semantic find-and-replace using tree-sitter-based macro expansion

Isaac Clayton 15 Nov 10, 2022