Rust错误处理库tor-error的使用:高效管理与自定义Tor网络错误类型
Rust错误处理库tor-error的使用:高效管理与自定义Tor网络错误类型
tor-error简介
tor-error
是用于Tor和Arti项目中的错误处理支持库。它主要提供以下功能:
ErrorKind
枚举类型- 关联的
HasKind
trait - 其他一些支持上层依赖栈错误处理的辅助功能
特性
backtrace
:在内部错误中启用回溯(默认启用)
实验性特性
这些API不包含在语义版本控制保证中,可能会在补丁版本间破坏或移除:
experimental-api
:向公共接口添加额外的非稳定API
许可证
MIT OR Apache-2.0
安装
在项目目录中运行以下Cargo命令:
cargo add tor-error
或者在Cargo.toml中添加:
tor-error = "0.32.0"
完整示例代码
以下是一个扩展的使用tor-error
的完整示例,展示更复杂的Tor网络错误处理:
use tor_error::{ErrorKind, HasKind};
use std::error::Error;
use std::fmt;
// 自定义Tor网络错误类型
#[derive(Debug)]
struct TorNetworkError {
kind: ErrorKind,
message: String,
source: Option<Box<dyn Error>>, // 错误来源
}
impl TorNetworkError {
// 创建新错误
fn new(kind: ErrorKind, message: &str) -> Self {
TorNetworkError {
kind,
message: message.to_string(),
source: None,
}
}
// 创建带源错误的错误
fn with_source(kind: ErrorKind, message: &str, source: Box<dyn Error>) -> Self {
TorNetworkError {
kind,
message: message.to_string(),
source: Some(source),
}
}
// 获取错误严重性
fn severity(&self) -> &str {
match self.kind {
ErrorKind::Internal => "Critical",
ErrorKind::TorProtocolViolation => "High",
_ => "Medium",
}
}
}
impl fmt::Display for TorNetworkError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "[{:?}] Tor Error: {}", self.kind, self.message)?;
if let Some(source) = &self.source {
write!(f, " (Source: {})", source)?;
}
Ok(())
}
}
impl Error for TorNetworkError {
fn source(&self) -> Option<&(dyn Error + 'static)> {
self.source.as_deref()
}
}
impl HasKind for TorNetworkError {
fn kind(&self) -> ErrorKind {
self.kind
}
}
// 模拟底层IO错误
#[derive(Debug)]
struct IoError {
details: String,
}
impl fmt::Display for IoError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "IO Error: {}", self.details)
}
}
impl Error for IoError {}
fn simulate_network_operation() -> Result<(), Box<dyn Error>> {
// 模拟底层IO错误
let io_err = IoError {
details: "Connection timed out".to_string(),
};
// 将IO错误包装为Tor网络错误
Err(Box::new(TorNetworkError::with_source(
ErrorKind::Internal,
"Failed to read from network socket",
Box::new(io_err),
)))
}
fn main() -> Result<(), Box<dyn Error>> {
match simulate_network_operation() {
Ok(_) => println!("Operation succeeded"),
Err(e) => {
// 处理错误
if let Some(tor_err) = e.downcast_ref::<TorNetworkError>() {
println!("Tor Network Error occurred:");
println!("Error: {}", tor_err);
println!("Kind: {:?}", tor_err.kind());
println!("Severity: {}", tor_err.severity());
if let Some(source) = tor_err.source() {
println!("Caused by: {}", source);
}
// 根据错误类型采取不同措施
match tor_err.kind() {
ErrorKind::Internal => {
println!("Critical error - terminating connection");
}
ErrorKind::TorProtocolViolation => {
println!("Protocol violation - logging and continuing");
}
_ => {
println!("Other error - retrying operation");
}
}
} else {
println!("Unknown error: {}", e);
}
}
}
Ok(())
}
这个扩展示例展示了:
- 更复杂的自定义Tor网络错误类型,包含错误来源
- 错误严重性分级
- 错误链的包装和处理
- 使用
downcast_ref
进行错误类型检查 - 完整的错误处理流程
您可以根据实际需求进一步扩展,例如添加更多的错误种类或自定义错误处理方法。
1 回复
Rust错误处理库tor-error的使用:高效管理与自定义Tor网络错误类型
tor-error
是Tor项目中的一个错误处理库,专门用于处理Tor网络相关的错误情况。它提供了一套结构化的错误类型和实用工具,帮助开发者高效管理Tor网络应用中的错误。
主要特性
- 为Tor网络操作提供标准化的错误类型
- 支持错误链(Error chaining)和上下文信息
- 提供便捷的错误构建和转换方法
- 支持自定义错误类型扩展
基本使用方法
添加依赖
首先在Cargo.toml
中添加依赖:
[dependencies]
tor-error = "0.4"
基本错误处理
use tor_error::{ErrorKind, HasKind};
fn connect_to_tor() -> Result<(), tor_error::Error> {
// 模拟一个错误
Err(tor_error::Error::new(
ErrorKind::TorNetworkUnreachable,
"Failed to connect to Tor network"
))
}
fn main() {
match connect_to_tor() {
Ok(_) => println!("Connected successfully"),
Err(e) => {
println!("Error: {}", e);
println!("Error kind: {:?}", e.kind());
}
}
}
自定义错误类型
use tor_error::{ErrorKind, HasKind, Error};
#[derive(Debug, Clone)]
enum MyCustomError {
CircuitFailure,
AuthenticationFailed,
}
impl std::fmt::Display for MyCustomError {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
match self {
MyCustomError::CircuitFailure => write!(f, "Tor circuit failed"),
MyCustomError::AuthenticationFailed => write(f, "Authentication failed"),
}
}
}
impl std::error::Error for MyCustomError {}
impl HasKind for MyCustomError {
fn kind(&self) -> ErrorKind {
match self {
MyCustomError::CircuitFailure => ErrorKind::TorProtocolViolation,
MyCustomError::AuthenticationFailed => ErrorKind::TorAccessFailed,
}
}
}
fn custom_operation() -> Result<(), Error> {
// 模拟返回自定义错误
let custom_err = MyCustomError::CircuitFailure;
Err(Error::from(custom_err))
}
错误链和上下文
use tor-error::{Error, ErrorKind};
fn connect_to_relay() -> Result<(), Error> {
// 模拟一个底层IO错误
let io_err = std::io::Error::new(
std::io::ErrorKind::ConnectionRefused,
"Connection refused by relay"
);
// 添加上下文信息并转换为tor-error
Err(Error::from(io_err)
.with_source(ErrorKind::TorNetworkUnreachable)
.context("Failed to connect to Tor relay"))
}
fn main() {
if let Err(e) = connect_to_relay() {
println!("Error: {}", e);
println!("Full error chain:");
for cause in e.chain() {
println!("- {}", cause);
}
}
}
错误种类(ErrorKind)
tor-error
定义了一些常见的Tor网络错误种类:
pub enum ErrorKind {
/// 内部错误
Internal,
/// Tor协议违规
TorProtocolViolation,
/// 网络不可达
TorNetworkUnreachable,
/// 访问被拒绝
TorAccessFailed,
/// 配置错误
TorConfigError,
/// 超时
TorTimeout,
/// 资源耗尽
TorResourceExhausted,
// ... 其他种类
}
高级用法
错误包装和转换
use tor_error::{Error, ErrorKind};
fn parse_tor_response(response: &str) -> Result<(), Error> {
// 假设解析失败
let parse_err = "Invalid Tor response format".to_string();
// 将字符串错误转换为tor-error
Err(Error::new(ErrorKind::TorProtocolViolation, parse_err))
}
fn handle_response() -> Result<(), Error> {
let response = "BAD_RESPONSE";
parse_tor_response(response).map_err(|e| {
// 添加上下文信息
e.context("Failed to process Tor server response")
})?;
Ok(())
}
批量错误处理
use tor-error::{Error, ErrorKind};
fn check_multiple_relays() -> Result<(), Vec<Error>> {
let mut errors = Vec::new();
for relay in &["relay1", "relay2", "relay3"] {
if let Err(e) = check_relay(relay) {
errors.push(e);
}
}
if errors.is_empty() {
Ok(())
} else {
Err(errors)
}
}
fn check_relay(relay: &str) -> Result<(), Error> {
// 模拟检查失败
Err(Error::new(
ErrorKind::TorNetworkUnreachable,
format!("Relay {} unavailable", relay)
))
}
完整示例代码
下面是一个综合使用tor-error
的完整示例,展示了从基本错误处理到自定义错误类型的完整流程:
use tor_error::{Error, ErrorKind, HasKind};
use std::error::Error as StdError;
// 自定义错误类型
#[derive(Debug)]
enum TorAppError {
ConnectionFailed,
InvalidResponse,
AuthenticationError,
}
impl std::fmt::Display for TorAppError {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
match self {
TorAppError::ConnectionFailed => write!(f, "Tor connection failed"),
TorAppError::InvalidResponse => write!(f, "Invalid response from Tor network"),
TorAppError::AuthenticationError => write!(f, "Authentication failed"),
}
}
}
impl StdError for TorAppError {}
impl HasKind for TorAppError {
fn kind(&self) -> ErrorKind {
match self {
TorAppError::ConnectionFailed => ErrorKind::TorNetworkUnreachable,
TorAppError::InvalidResponse => ErrorKind::TorProtocolViolation,
TorAppError::AuthenticationError => ErrorKind::TorAccessFailed,
}
}
}
// 模拟Tor连接函数
fn connect_to_tor() -> Result<(), Error> {
// 这里模拟一个底层IO错误
let io_error = std::io::Error::new(
std::io::ErrorKind::ConnectionRefused,
"Connection refused by Tor node"
);
// 转换为tor-error并添加上下文
Err(Error::from(io_error)
.with_source(ErrorKind::TorNetworkUnreachable)
.context("Failed to establish Tor connection"))
}
// 模拟处理Tor响应
fn process_tor_response(response: &str) -> Result<(), Error> {
if response.is_empty() {
// 使用自定义错误类型
let custom_error = TorAppError::InvalidResponse;
return Err(Error::from(custom_error)
.context("Empty response received"));
}
// 模拟处理逻辑
if response == "AUTH_FAILED" {
let auth_error = TorAppError::AuthenticationError;
return Err(Error::from(auth_error));
}
Ok(())
}
fn main() {
// 示例1: 处理连接错误
match connect_to_tor() {
Ok(_) => println!("Connected to Tor successfully"),
Err(e) => {
println!("Connection Error: {}", e);
println!("Error kind: {:?}", e.kind());
println!("Error chain:");
for cause in e.chain() {
println!("- {}", cause);
}
}
}
// 示例2: 处理响应错误
let responses = ["GOOD", "", "AUTH_FAILED"];
for response in responses.iter() {
println!("\nProcessing response: {}", response);
match process_tor_response(response) {
Ok(_) => println!("Response processed successfully"),
Err(e) => {
println!("Error processing response: {}", e);
println!("Error kind: {:?}", e.kind());
}
}
}
// 示例3: 批量错误处理
let mut all_errors = Vec::new();
for node in &["node1", "node2", "node3"] {
if let Err(e) = check_node_availability(node) {
all_errors.push(e);
}
}
if !all_errors.is_empty() {
println!("\nBatch errors:");
for err in all_errors {
println!("- {}", err);
}
}
}
fn check_node_availability(node: &str) -> Result<(), Error> {
// 模拟节点检查
if node == "node2" {
Err(Error::new(
ErrorKind::TorNetworkUnreachable,
format!("Node {} is unreachable", node)
))
} else {
Ok(())
}
}
最佳实践
- 尽可能使用
tor-error
提供的错误类型而不是基础错误类型 - 为自定义错误实现
HasKind
trait以保持一致性 - 使用
context()
方法添加上下文信息 - 利用错误链来保留完整的错误信息
- 根据错误种类(ErrorKind)实现不同的恢复逻辑
tor-error
为Tor网络应用提供了强大而灵活的错误处理能力,通过结构化的错误类型和丰富的工具方法,可以显著提高错误处理代码的可读性和可维护性。