Rust错误处理库stable-eyre的使用,stable-eyre提供稳定且可扩展的错误报告功能

Rust错误处理库stable-eyre的使用

stable-eyre是一个为eyre库提供自定义EyreHandler类型的库,它提供了与eyre::DefaultHandler相同的功能,但通过使用backtrace-rs捕获backtrace::Backtrace来在稳定版Rust上工作。

设置

在您的Cargo.toml文件中添加以下依赖:

[dependencies]
stable-eyre = "0.2"

在构造任何eyre::Report类型之前,需要先安装hook处理程序。

示例

内容中提供的示例代码:

use stable_eyre::eyre::{eyre, Report, WrapErr};

fn main() -> Result<(), Report> {
    stable_eyre::install()?;

    let e: Report = eyre!("oh no this program is just bad!");

    Err(e).wrap_err("usage example successfully experienced a failure")
}

完整示例

下面是一个更完整的示例,展示如何使用stable-eyre进行错误处理和包装:

use stable_eyre::eyre::{eyre, Report, WrapErr};
use std::fs::File;
use std::io::Read;

// 自定义错误类型
#[derive(Debug)]
struct CustomError {
    message: String,
}

// 读取文件内容的函数,可能返回错误
fn read_file(path: &str) -> Result<String, Report> {
    let mut file = File::open(path)
        .wrap_err(format!("Failed to open file at path: {}", path))?;
    
    let mut contents = String::new();
    file.read_to_string(&mut contents)
        .wrap_err(format!("Failed to read file: {}", path))?;
    
    Ok(contents)
}

fn main() -> Result<(), Report> {
    // 安装stable-eyre错误报告钩子
    stable_eyre::install()?;

    // 示例1: 创建基本错误
    let basic_error: Report = eyre!("This is a basic error message");
    println!("Basic error: {:?}", basic_error);

    // 示例2: 包装错误
    let wrapped_error = Err::<(), _>(basic_error)
        .wrap_err("Additional context for the error")?;
    
    // 示例3: 实际文件操作错误
    match read_file("nonexistent.txt") {
        Ok(contents) => println!("File contents: {}", contents),
        Err(e) => {
            println!("Error reading file: {:?}", e);
            // 可以在这里添加更多错误处理逻辑
        }
    }

    Ok(())
}

这个示例展示了:

  1. 如何初始化stable-eyre
  2. 创建基本错误
  3. 包装错误添加上下文
  4. 在实际IO操作中使用错误处理
  5. 错误匹配和处理

许可证

stable-eyre采用双许可证:

  • Apache License, Version 2.0
  • MIT license

您可以选择其中任何一种许可方式。除非您明确说明,否则任何提交到这个crate的贡献都将被视为双许可。


1 回复

Rust错误处理库stable-eyre的使用指南

stable-eyre是一个Rust错误处理库,提供了稳定且可扩展的错误报告功能。它是eyre库的一个稳定分支,专注于提供可靠的错误处理体验。

主要特性

  • 稳定的错误报告API
  • 可扩展的错误上下文
  • 美观的错误输出格式
  • std::error::Error兼容
  • 支持错误链追踪

安装方法

在Cargo.toml中添加依赖:

[dependencies]
stable-eyre = "0.2"

基本使用方法

1. 初始化

use stable_eyre::eyre;

fn main() -> eyre::Result<()> {
    stable_eyre::install()?;
    
    // 你的代码...
    Ok(())
}

2. 创建和返回错误

use stable_eyre::eyre::{eyre, WrapErr};

fn divide(a: i32, b: i32) -> eyre::Result<i32> {
    if b == 0 {
        return Err(eyre!("Division by zero"));
    }
    Ok(a / b)
}

fn calculate() -> eyre::Result<()> {
    let result = divide(10, 0).wrap_err("Failed to calculate division")?;
    println!("Result: {}", result);
    Ok(())
}

3. 添加错误上下文

use stable_eyre::eyre::{eyre, Context};

fn read_config() -> eyre::Result<String> {
    std::fs::read_to_string("config.toml")
        .context("Failed to read config file")
}

fn load_app() -> eyre::Result<()> {
    let config = read_config()
        .context("Could not load application configuration")?;
    // 使用配置...
    Ok(())
}

高级用法

自定义错误报告

use stable_eyre::eyre::{eyre, Report};
use std::error::Error;

fn process_data(data: &str) -> eyre::Result<()> {
    if data.is_empty() {
        let mut report = Report::new(eyre!("Empty data provided"));
        report = report.wrap_err("Data processing failed");
        report = report.wrap_err("Application error");
        return Err(report);
    }
    // 处理数据...
    Ok(())
}

错误链追踪

use stable_eyre::eyre::{eyre, Report};

fn inner_function() -> eyre::Result<()> {
    Err(eyre!("Something went wrong at the lowest level"))
}

fn middle_function() -> eyre::Result<()> {
    inner_function().wrap_err("Middle layer error")?;
    Ok(())
}

fn outer_function() -> eyre::Result<()> {
    middle_function().wrap_err("Outer layer error")?;
    Ok(())
}

fn main() -> eyre::Result<()> {
    stable_eyre::install()?;
    
    if let Err(report) = outer_function() {
        eprintln!("Error: {:?}", report);
    }
    
    Ok(())
}

错误输出示例

当错误发生时,stable-eyre会生成格式良好的错误报告:

Error: Outer layer error

Caused by:
    0: Middle layer error
    1: Something went wrong at the lowest level

与标准库互操作

use stable_eyre::eyre;
use std::io;

fn std_error_to_eyre() -> eyre::Result<()> {
    let result: Result<(), io::Error> = Err(io::Error::new(io::ErrorKind::Other, "IO error"));
    let eyre_result = result.map_err(|e| eyre!(e))?;
    Ok(eyre_result)
}

完整示例DEMO

下面是一个结合上述所有功能的完整示例:

use stable_eyre::eyre::{self, eyre, Context, Report, WrapErr};
use std::fs;
use std::io;

// 初始化stable-eyre
fn setup() -> eyre::Result<()> {
    stable_eyre::install()?;
    Ok(())
}

// 基础错误示例
fn basic_error_example() -> eyre::Result<()> {
    let value = "not_a_number".parse::<i32>()?;
    Ok(())
}

// 添加上下文
fn context_example() -> eyre::Result<()> {
    let config = fs::read_to_string("missing_file.txt")
        .context("Failed to read config file")?;
    Ok(())
}

// 错误链
fn error_chain_example() -> eyre::Result<()> {
    inner_function().wrap_err("Middle layer error")?;
    Ok(())
}

fn inner_function() -> eyre::Result<()> {
    Err(eyre!("Core error occurred"))
}

// 自定义报告
fn custom_report_example() -> eyre::Result<()> {
    let data = "";
    if data.is_empty() {
        let mut report = Report::new(eyre!("Empty input data"));
        report = report.wrap_err("Validation failed");
        return Err(report);
    }
    Ok(())
}

// 标准库错误转换
fn std_error_example() -> eyre::Result<()> {
    let result: Result<(), io::Error> = Err(io::Error::new(
        io::ErrorKind::NotFound,
        "File not found"
    ));
    result.map_err(|e| eyre!(e))?;
    Ok(())
}

fn main() -> eyre::Result<()> {
    setup()?;

    // 演示各种错误处理场景
    if let Err(e) = basic_error_example() {
        eprintln!("Basic error example failed: {:?}", e);
    }

    if let Err(e) = context_example() {
        eprintln!("Context example failed: {:?}", e);
    }

    if let Err(e) = error_chain_example() {
        eprintln!("Error chain example failed: {:?}", e);
    }

    if let Err(e) = custom_report_example() {
        eprintln!("Custom report example failed: {:?}", e);
    }

    if let Err(e) = std_error_example() {
        eprintln!("Std error example failed: {:?}", e);
    }

    Ok(())
}

这个完整示例展示了:

  1. 库的初始化和设置
  2. 基础错误处理
  3. 添加上下文信息
  4. 错误链追踪
  5. 自定义错误报告
  6. 标准库错误转换

运行此程序将演示各种错误场景,并显示格式良好的错误报告。

回到顶部