Skip to content

Rust Error Handling Advanced — Custom Error Types, thiserror, and anyhow

DodaTech Updated 2026-06-28 1 min read

In this tutorial, you will learn about Rust Error Handling Advanced. We cover key concepts, practical examples, and best practices to help you master this topic.

Rust advanced error handling uses thiserror for custom error types, anyhow for application errors, and backtrace for debugging.

What You'll Learn

  • Custom error types
  • thiserror derive macro
  • anyhow for app errors
  • Error chaining

Why It Matters

Proper error handling improves debugging. DodaZIP uses thiserror for library errors and anyhow for application errors.

Real-World Use

Library error types, application error handling, error propagation in services.

use std::fmt;
use thiserror::Error;

#[derive(Error, Debug)]
pub enum DataError {
    #[error("not found: {0}")]
    NotFound(String),

    #[error("permission denied")]
    PermissionDenied,

    #[error("validation failed: {msg}")]
    Validation { msg: String },

    #[error("io error: {0}")]
    Io(#[from] std::io::Error),
}

// Manual implementation (without thiserror)
#[derive(Debug)]
pub enum ManualError {
    NotFound(String),
    IoError(std::io::Error),
}

impl fmt::Display for ManualError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            ManualError::NotFound(id) => write!(f, "Not found: {}", id),
            ManualError::IoError(e) => write!(f, "IO error: {}", e),
        }
    }
}

impl std::error::Error for ManualError {}

use anyhow::{Result, Context};

fn read_config(path: &str) -> Result<String> {
    std::fs::read_to_string(path)
        .with_context(|| format!("Failed to read config from {}", path))
}

fn main() -> Result<()> {
    let content = read_config("config.toml")
        .context("Could not load application config")?;
    println!("Config: {}", content);
    Ok(())
}

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro