Rust错误处理库garando_errors的使用,garando_errors提供高效且可定制的错误处理解决方案
Rust错误处理库garando_errors的使用,garando_errors提供高效且可定制的错误处理解决方案
garando_errors是Rust编译器不稳定库librustc_errors的一个稳定版本实现。它提供了高效且可定制的错误处理解决方案,能够在Rust稳定版中使用。
安装
在Cargo.toml中添加依赖:
garando_errors = "0.1.0"
或者运行:
cargo add garando_errors
示例使用
下面是一个使用garando_errors的完整示例:
use garando_errors::{emitter::Emitter, Handler};
use garando_pos::{Span, MultiSpan};
use std::path::PathBuf;
fn main() {
// 创建错误处理程序
let mut handler = Handler::with_tty_emitter(
false, // 是否颜色化输出
false, // 是否显示错误说明
false, // 是否显示错误代码
None, // 可选的文件名映射
);
// 创建一个错误位置(span)
let span = Span::new(
0, // 起始位置
10, // 结束位置
0, // 上下文索引
);
// 创建多位置错误
let multi_span = MultiSpan::from_span(span);
// 发出错误
handler.err(
"这是一个示例错误", // 错误消息
"E0001", // 错误代码
multi_span, // 错误位置
None, // 可选帮助消息
None, // 可选错误说明
);
// 发出警告
handler.warn(
"这是一个示例警告",
"W0001",
multi_span,
None,
None,
);
// 发出帮助信息
handler.help(
"这是一个示例帮助信息",
multi_span,
None,
);
}
特性
- 提供TTY和非TTY输出支持
- 支持颜色化输出
- 可以添加错误代码和说明
- 支持多位置错误标记
- 可定制的错误格式
许可证
garando_errors采用双许可证:
- Apache License, Version 2.0
- MIT license
构建状态
完整示例demo
以下是一个更完整的示例,展示了如何使用garando_errors处理多个错误和位置:
use garando_errors::{emitter::Emitter, Handler};
use garando_pos::{Span, MultiSpan};
use std::path::PathBuf;
fn main() {
// 创建错误处理程序,启用颜色输出
let mut handler = Handler::with_tty_emitter(
true, // 启用颜色化输出
true, // 显示错误说明
true, // 显示错误代码
None, // 可选的文件名映射
);
// 创建多个错误位置
let span1 = Span::new(0, 10, 0); // 第一个错误位置
let span2 = Span::new(15, 25, 0); // 第二个错误位置
// 创建多位置错误
let multi_span = MultiSpan::from_spans(vec![span1, span2]);
// 发出带有帮助信息的错误
handler.err(
"变量未声明", // 错误消息
"E0425", // 错误代码
multi_span, // 错误位置
Some("尝试声明这个变量或检查拼写"), // 帮助消息
Some("未声明的变量错误"), // 错误说明
);
// 发出警告
handler.warn(
"未使用的变量",
"W0161",
MultiSpan::from_span(span1),
Some("考虑删除这个未使用的变量"),
Some("未使用变量警告"),
);
// 发出帮助信息
handler.help(
"更多帮助信息请查看文档",
MultiSpan::from_span(span2),
Some("https://example.com/docs"),
);
// 发出多个错误
for i in 0..3 {
let span = Span::new(i * 10, i * 10 + 5, 0);
handler.err(
&format!("示例错误 {}", i + 1),
&format!("E{:04}", 1000 + i),
MultiSpan::from_span(span),
None,
None,
);
}
}
1 回复
Rust错误处理库garando_errors使用指南
garando_errors
是一个为Rust设计的高效且可定制的错误处理库,它提供了灵活的错误定义和处理机制,特别适合需要细粒度错误控制的应用程序。
主要特性
- 高效的错误处理机制
- 完全可定制的错误类型
- 简洁的错误定义语法
- 支持错误链和上下文信息
- 与标准库
std::error::Error
兼容
基本使用方法
添加依赖
首先在Cargo.toml
中添加依赖:
[dependencies]
garando_errors = "0.1"
定义自定义错误
use garando_errors::{Error, ErrorKind};
// 定义错误种类
#[derive(Debug, ErrorKind)]
pub enum MyErrorKind {
#[error("Invalid input")]
InvalidInput,
#[error("Network error")]
NetworkError,
#[error("Database error: {0}")]
DatabaseError(String),
}
// 定义错误类型
#[derive(Debug, Error)]
#[error(kind = MyErrorKind)]
pub struct MyError {
pub source: Option<Box<dyn std::error::Error>>,
pub context: Vec<String>,
}
使用自定义错误
fn validate_input(input: &str) -> Result<(), MyError> {
if input.is_empty() {
Err(MyErrorKind::InvalidInput.into())
} else {
Ok(())
}
}
fn connect_to_db() -> Result<(), MyError> {
// 模拟数据库连接失败
Err(MyErrorKind::DatabaseError("Connection timed out".to_string()).into())
}
fn process_data(input: &str) -> Result<(), MyError> {
validate_input(input)?;
connect_to_db()?;
Ok(())
}
添加错误上下文
use garando_errors::Context;
fn complex_operation() -> Result<(), MyError> {
let result = process_data("");
result.context("Failed to process data in complex operation")?;
Ok(())
}
错误处理示例
fn main() {
match complex_operation() {
Ok(_) => println!("Operation succeeded"),
Err(e) => {
eprintln!("Error: {}", e);
// 打印完整的错误链
if let Some(source) = e.source() {
eprintln!("Caused by: {}", source);
}
// 打印上下文信息
if !e.context.is_empty() {
eprintln!("Context:");
for ctx in &e.context {
eprintln!("- {}", ctx);
}
}
}
}
}
高级用法
自定义错误转换
impl From<std::io::Error> for MyError {
fn from(err: std::io::Error) -> Self {
MyErrorKind::NetworkError.with_source(err)
}
}
组合多个错误
fn multi_step_operation() -> Result<(), MyError> {
let op1 = step_one().context("Step one failed")?;
let op2 = step_two().context("Step two failed")?;
step_three(op1, op2).context("Step three failed")
}
条件错误构建
fn conditional_error(condition: bool) -> Result<(), MyError> {
if condition {
Ok(())
} else {
Err(MyErrorKind::InvalidInput
.with_message("Condition was false")
.with_context("Additional context information"))
}
}
性能建议
- 对于频繁返回的错误,考虑使用
&'static str
而不是String
来存储错误信息 - 使用
ErrorKind
的简单变体(不带附加数据)可以获得最佳性能 - 只有在需要时才附加上下文信息
完整示例demo
下面是一个使用garando_errors库的完整示例,展示了从错误定义到处理的完整流程:
use garando_errors::{Error, ErrorKind, Context};
// 1. 定义错误种类
#[derive(Debug, ErrorKind)]
pub enum AppErrorKind {
#[error("Invalid input: {0}")]
InvalidInput(String),
#[error("IO error")]
IoError,
#[error("Calculation error")]
CalcError,
}
// 2. 定义错误类型
#[derive(Debug, Error)]
#[error(kind = AppErrorKind)]
pub struct AppError {
pub source: Option<Box<dyn std::error::Error>>,
pub context: Vec<String>,
}
// 3. 实现从std::io::Error转换
impl From<std::io::Error> for AppError {
fn from(err: std::io::Error) -> Self {
AppErrorKind::IoError.with_source(err)
}
}
// 示例函数:读取文件内容
fn read_file(path: &str) -> Result<String, AppError> {
std::fs::read_to_string(path)
.map_err(|e| e.into())
.context(format!("Failed to read file: {}", path))?
}
// 示例函数:处理业务逻辑
fn process_content(content: &str) -> Result<f64, AppError> {
if content.is_empty() {
return Err(AppErrorKind::InvalidInput("Empty content".to_string()).into());
}
// 模拟计算
content.parse::<f64>()
.map_err(|_| AppErrorKind::CalcError.into())
}
// 组合操作
fn run_operations(file_path: &str) -> Result<f64, AppError> {
let content = read_file(file_path)?;
let result = process_content(&content)?;
Ok(result)
}
fn main() {
match run_operations("data.txt") {
Ok(value) => println!("Result: {}", value),
Err(e) => {
eprintln!("Error occurred: {}", e);
// 打印错误链
if let Some(source) = e.source() {
eprintln!("Caused by: {}", source);
}
// 打印上下文
if !e.context.is_empty() {
eprintln!("Context:");
for ctx in &e.context {
eprintln!("- {}", ctx);
}
}
}
}
}
这个完整示例展示了:
- 自定义错误类型的定义
- 标准库错误的转换
- 错误上下文的使用
- 多步骤操作中的错误处理
- 完整的错误打印和诊断信息
你可以根据实际需求调整错误类型和业务逻辑,garando_errors提供了灵活的错误处理机制来满足各种场景的需求。