Rust错误处理库ckb-error的使用:高效自定义错误类型与错误管理解决方案

Rust错误处理库ckb-error的使用:高效自定义错误类型与错误管理解决方案

ckb-error简介

ckb-error是Nervos Network的CKB项目中的一个组件,用于在整个ckb crate中提供基础错误类型支持。

最低支持的Rust版本(MSRV)

该crate要求的最低Rust版本为1.85.0

安装

在项目目录中运行以下Cargo命令:

cargo add ckb-error

或者在Cargo.toml中添加以下行:

ckb-error = "0.202.0"

完整示例代码

以下是一个使用ckb-error创建自定义错误类型的完整示例:

use ckb_error::{Error, ErrorKind};
use std::fmt;

// 1. 定义你自己的错误类型
#[derive(Debug)]
struct MyCustomError {
    details: String,
}

impl MyCustomError {
    fn new(msg: &str) -> MyCustomError {
        MyCustomError {
            details: msg.to_string(),
        }
    }
}

impl fmt::Display for MyCustomError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.details)
    }
}

// 2. 实现std::error::Error trait
impl std::error::Error for MyCustomError {
    fn description(&self) -> &str {
        &self.details
    }
}

// 3. 定义你的错误种类
#[derive(Debug, Clone)]
enum MyErrorKind {
    InputError,
    ProcessingError,
    OutputError,
}

impl ErrorKind for MyErrorKind {}

// 4. 使用ckb-error的Error类型
fn might_fail(input: &str) -> Result<(), Error> {
    if input.is_empty() {
        return Err(Error::new(
            MyErrorKind::InputError,
            Box::new(MyCustomError::new("Input cannot be empty")),
        ));
    }
    
    // 其他逻辑...
    Ok(())
}

fn main() {
    match might_fail("") {
        Ok(_) => println!("Success!"),
        Err(e) => {
            println!("Error occurred: {}", e);
            // 你可以访问错误种类
            if let Some(kind) = e.kind().downcast_ref::<MyErrorKind>() {
                match kind {
                    MyErrorKind::InputError => println!("It was an input error"),
                    MyErrorKind::ProcessingError => println!("It was a processing error"),
                    MyErrorKind::OutputError => println!("It was an output error"),
                }
            }
        }
    }
}

文档

更多详细使用说明请参考官方文档

仓库

项目源码位于

许可证

该crate使用MIT许可证


1 回复

Rust错误处理库ckb-error的使用:高效自定义错误类型与错误管理解决方案

介绍

ckb-error 是一个专门为 Rust 设计的错误处理库,它提供了高效的自定义错误类型和错误管理解决方案。这个库特别适合需要精细控制错误处理流程的项目,能够帮助开发者创建结构化的错误类型,并提供便捷的错误传播机制。

主要特性

  1. 支持自定义错误类型,可以携带丰富的上下文信息
  2. 提供错误码机制,便于错误分类和识别
  3. 支持错误嵌套,保留完整的错误链
  4. 与标准库的 std::error::Error trait 兼容
  5. 性能优化,错误处理开销小

完整示例代码

use ckb_error::{Error, ErrorKind, Context, ErrorFormatter};

// 1. 定义自定义错误类型
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum AppError {
    InvalidInput(String),
    NetworkError(String),
    DatabaseError(String),
}

// 2. 实现从自定义错误到ckb-error的转换
impl From<AppError> for Error {
    fn from(error: AppError) -> Self {
        match error {
            AppError::InvalidInput(msg) => 
                Error::new(ErrorKind::InvalidInput, msg),
            AppError::NetworkError(msg) => 
                Error::new(ErrorKind::Network, msg),
            AppError::DatabaseError(msg) => 
                Error::new(ErrorKind::Database, msg),
        }
    }
}

// 3. 业务函数示例
fn validate_user_input(input: &str) -> Result<(), Error> {
    if input.is_empty() {
        return Err(AppError::InvalidInput("输入不能为空".to_string()).into());
    }
    if input.len() > 100 {
        return Err(AppError::InvalidInput("输入长度超过限制".to_string()).into());
    }
    Ok(())
}

// 4. 使用上下文添加额外信息
fn process_user_data(input: &str) -> Result<(), Error> {
    let ctx = Context::new("处理用户数据");
    validate_user_input(input).context(ctx)?;
    // 其他处理逻辑...
    Ok(())
}

// 5. 自定义错误格式化
struct CustomFormatter;
impl ErrorFormatter for CustomFormatter {
    fn format(&self, error: &Error) -> String {
        format!("[应用错误] 类型: {:?}, 原因: {}", error.kind(), error)
    }
}

// 6. 错误处理主函数
fn main() {
    // 测试错误处理
    match process_user_data("") {
        Ok(_) => println!("操作成功"),
        Err(e) => {
            // 使用自定义格式化
            let formatter = CustomFormatter;
            println!("{}", formatter.format(&e));
            
            // 错误链追踪
            println!("\n错误链:");
            let mut current = &e as &dyn std::error::Error;
            while let Some(source) = current.source() {
                println!("- {}", source);
                current = source;
            }
        }
    }
    
    // 测试标准库错误转换
    match read_config_file() {
        Ok(_) => println!("配置文件读取成功"),
        Err(e) => println!("配置文件错误: {}", e),
    }
}

// 7. 标准库错误转换示例
fn read_config_file() -> Result<(), Error> {
    let result = std::fs::read_to_string("config.toml")
        .map_err(|e| Error::new(ErrorKind::Io, "IO错误").with_cause(e))?;
    // 处理配置...
    Ok(())
}

代码说明

  1. 自定义错误类型:定义了AppError枚举,包含三种错误变体,每种都可以携带详细错误信息。

  2. 错误转换:实现了From<AppError> for Error,将自定义错误转换为ckb-error类型。

  3. 业务验证函数validate_user_input函数展示了如何使用自定义错误。

  4. 上下文添加process_user_data展示了如何使用Context为错误添加上下文信息。

  5. 自定义格式化CustomFormatter实现了自定义错误信息格式。

  6. 主错误处理:展示了错误匹配、自定义格式化和错误链追踪。

  7. 标准库错误转换read_config_file展示了如何将标准库IO错误转换为ckb-error。

最佳实践建议

  1. 为不同模块定义专属错误类型,提高错误处理精度
  2. 重要错误添加错误码,便于日志分析和监控
  3. 公共API应提供清晰的错误文档说明
  4. 性能敏感路径考虑使用轻量级错误变体
  5. 保持错误链完整,便于调试复杂问题
回到顶部