#error

debug_err

A minimal error handling library

1 unstable release

Uses new Rust 2024

0.1.0 Nov 26, 2025

#142 in #error

22 downloads per month
Used in 3 crates

MIT license

7KB

An error handling library with under 50 lines of code and no dependencies, that keeps track of the source location of every error. DebugErr identifies the crate name, file name and line number of every error event.

The Basics

To build an error:

use debug_err::{DebugErr, src};

pub fn divide(num: f32, denom: f32) -> Result<f32, DebugErr> {
    if denom == 0.0 { Err(src!("Denominator must not be zero.")) }
    Ok(num / denom)
}

Coercing other error types to DebugErr

This extracts the message from another error type

use debug_err::{DebugErr, src};

let num: f32 = "abc".parse().map_err(|e| src!("Failed to parse with error '{e}'"))?;

Coercing DebugErr to other error types.

The cleanest method is just to directly use DebugErr in your library, and construct and return errors of this type, but if you still need to build your own error types then,

use {
    debug_err::{DebugErr, src},
    std::fmt,
};

#[derive(Clone, Debug)]
pub struct OwnError(DebugErr);

// Uses ``DebugErr``'s ``Display`` implementation.
impl fmt::Display for OwnError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{}", self.0)
    }
}

// This is used to coerce ``DebugErr`` into one's own type using the ``?`` operator,
// so that ``DebugErr`` doesn't have to be coerced explicitly.
impl From<DebugErr> for OwnError {
    fn from(debug: DebugErr) -> Self { OwnError(debug) }
}

// and then at the error construction site,

type Result<T> = std::result::Result<T, OwnError>;

pub fn divide(num: f32, denom: f32) -> Result<f32> {
    if denom == 0.0 { return Err(src!("Denominator must not be zero."))? }
    Ok(num / denom)
}

pub fn parse(num: &str) -> Result<f32> {
    let f: f32 = num.parse().map_err(|e| src!("Failed to parse '{num}' with error: {e}"))?;
    Ok(f)
}

No runtime deps