Rust:專業級錯誤處理工具 thiserror 詳解

Rust:專業級錯誤處理工具 thiserror 詳解

thiserror 是 Rust 中用于高效定義自定義錯誤類型的庫,特別適合庫開發。相比 anyhow 的應用級錯誤處理,thiserror 提供更精確的錯誤控制,讓庫用戶能模式匹配具體錯誤。


📦 基本安裝

Cargo.toml 中添加:

[dependencies]
thiserror = "1.0"

🧩 核心功能

1. 基礎錯誤定義

use thiserror::Error;#[derive(Error, Debug)]
enum MyError {#[error("File not found: {0}")]NotFound(String),#[error("I/O error occurred")]Io(#[from] std::io::Error),#[error("Validation failed for {field}: {reason}")]Validation {field: &'static str,reason: String,},
}

2. 自動實現特征

自動為你的類型實現:

  • std::error::Error
  • Display(通過 #[error] 屬性)
  • From(通過 #[from] 屬性)

🛠? 屬性詳解

1. #[error("格式化字符串")]

定義錯誤的顯示信息:

#[error("Invalid value: {value} (allowed: {allowed_values:?})")]
InvalidValue {value: i32,allowed_values: Vec<i32>,
}

調用:

println!("{}", MyError::InvalidValue {value: 42,allowed_values: vec![1, 2, 3]
});
// 輸出: Invalid value: 42 (allowed: [1, 2, 3])

2. #[source]

標記錯誤來源(自動實現 Error::source):

#[derive(Error, Debug)]
#[error("Config load failed")]
struct ConfigError {#[source]   // 標記錯誤來源字段source: std::io::Error,
}

3. #[from]

自動實現 From 轉換:

#[derive(Error, Debug)]
enum ParseError {#[error("Integer parsing failed")]Int(#[from] std::num::ParseIntError),#[error("Float parsing failed")]Float(#[from] std::num::ParseFloatError),
}// 自動轉換
fn parse(s: &str) -> Result<f64, ParseError> {let parts: Vec<&str> = s.split(':').collect();let x: i32 = parts[0].parse()?;  // 自動轉為 ParseError::Intlet y: f64 = parts[1].parse()?;  // 自動轉為 ParseError::FloatOk((x as f64) * y)
}

4. #[backtrace]

自動捕獲回溯信息:

#[derive(Error, Debug)]
#[error("Connection failed")]
struct ConnectionError {#[backtrace]   // 自動記錄回溯source: std::io::Error,
}

📚 結構體錯誤定義

#[derive(Error, Debug)]
#[error("Database error (code {code}): {message}")]
struct DbError {code: u32,message: String,#[source]inner: diesel::result::Error, // 底層錯誤
}

🔀 錯誤轉換

#[derive(Error, Debug)]
enum AppError {#[error("HTTP error: {0}")]Http(#[from] HttpError),#[error("Database error")]Db(#[from] DbError),
}fn handle_request() -> Result<(), AppError> {let data = fetch_data()?;       // HttpError -> AppError::Httpsave_to_db(&data)?;             // DbError -> AppError::DbOk(())
}

? 實用技巧

1. 添加額外上下文

fn read_config() -> Result<Config, MyError> {let path = "config.toml";let content = std::fs::read_to_string(path).map_err(|e| MyError::Io(e).context(format!("Failed to read {}", path)))?;// ...
}

2. 條件性字段

#[derive(Error, Debug)]
#[error("Operation failed{}{}", .details.as_ref().map(|s| format!(": {}", s)).unwrap_or_default())]
struct OpError {details: Option<String>,#[source]source: anyhow::Error,
}

3. 組合使用宏

fn parse_number(s: &str) -> Result<i32, ParseError> {s.parse().map_err(|e| {// 添加上下文信息ParseError::InvalidFormat {input: s.to_string(),#[source] e}})
}

💡 最佳實踐

  1. 庫開發優先:在編寫供他人使用的庫時使用 thiserror
  2. 精準錯誤類型:使用枚舉覆蓋所有可能錯誤
  3. 豐富錯誤信息:通過格式化字符串暴露有用信息
  4. 區分層級
    #[derive(Error, Debug)]
    enum ApiError {#[error(transparent)]Request(#[from] RequestError),#[error(transparent)]Parsing(#[from] ParseError),#[error("Authentication failed")]Auth,
    }
    

?? 常見錯誤解決

問題#[derive(Error)] 后未實現 Display
解決:確保每個變體都有 #[error] 屬性

問題source 字段不工作
解決

  1. 添加 #[source]#[from] 屬性
  2. 確保字段類型實現了 std::error::Error

🆚 thiserror vs anyhow

特性thiserroranyhow
適用場景庫開發應用開發
錯誤類型強類型自定義錯誤通用錯誤類型 (anyhow::Error)
模式匹配支持精確匹配只支持粗略匹配
上下文添加需手動實現內置 .context()
性能更高效(無堆分配)錯誤路徑有堆分配

當需要同時使用:

[dependencies]
anyhow = "1.0"
thiserror = "1.0"

完整文檔參考:thiserror on crates.io

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/92965.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/92965.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/92965.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Python網絡爬蟲(一) - 爬取靜態網頁

文章目錄一、靜態網頁概述1. 靜態網頁介紹2. 靜態網頁爬取技術Requests介紹二、安裝 Requests 庫三、發送請求并獲取響應1. 發送 GET 請求1.1 get() 方法介紹1.2 get() 方法簽名介紹1.3 get() 方法參數介紹1.4 示例&#xff1a;發送get請求2. 發送 POST 請求2.1 post() 方法介紹…

.NET/C# webapi框架下給swagger的api文檔中顯示注釋(可下載源碼)

bg&#xff1a;.NET/C#真的是越來越涼了。用的是.net9&#xff0c;創建完自帶一個天氣預報api拿來測試就行 1、在Controllers中弄多幾個&#xff0c;并寫上注釋 /// <summary> /// Post注釋 /// </summary> /// <returns></returns> [HttpPost] publ…

2508C++,檢測S模式

原文 可用Windows.System.Profile.WindowsIntegrityPolicy類檢測S模式. //C# using Windows.System.Profile; if (WindowsIntegrityPolicy.IsEnabled) {//系統在S模式if (WindowsIntegrityPolicy.CanDisable) {//系統在S模式,但可退出S模式suggestCompanion true;} else {//系…

Coding Exercising Day 9 of “Code Ideas Record“:StackQueue part 01

文章目錄1. Theoretical basisThe C standard library has multiple versions. To understand the implementation principles of stack and queue, we must know which STL version we are using.The stack and queue discussed next are data structures in *SGI STL*. Only …

Mysql數據倉庫備份腳本

Mysql數據倉庫備份腳本 #!/bin/bash# MySQL數據庫完整備份腳本 # 功能: 查詢所有數據庫 -> 分別導出 -> 壓縮打包# 配置區域 # MySQL連接信息 MYSQL_USER"root" MYSQL_PASSWORD"root" MYSQL_HOST"localhost" MYSQL_PORT"3306"…

基于嵌入式Linux RK3568 qt 車機系統開發

嵌入式系統、Qt/QML 與車機系統的發展趨勢分析 1. RK3568 開發板與 OpenGL ES 3 支持&#xff0c;為圖形應用打下堅實基礎 RK3568 是瑞芯微&#xff08;Rockchip&#xff09;推出的一款高性能、低功耗的64位處理器&#xff0c;廣泛用于工業控制、智能終端、嵌入式車載系統等領…

OceanBase架構設計

本文主要參考《大規模分布式存儲系統》 基本結構客戶端&#xff1a;發起請求。 RootServer&#xff1a;管理集群中的所有服務器&#xff0c;子表數據分布及副本管理&#xff0c;一般為一主一備&#xff0c;數據強同步。 UpdateServer&#xff1a;存儲增量變更數據&#xff0c;一…

[Element-plus]動態設置組件的語言

nuxt element-plus國際化vue element-plus國際化<template><div class"container"> <!-- <LangSwitcher />--><button click"toggle(zh-cn)">中文</button><button click"toggle(en)">English<…

【VS Code - Qt】如何基于Docker Linux配置Windows10下的VS Code,開發調試ARM 版的Qt應用程序?

如何在Windows 10上配置VS Code以開發和調試ARM版Qt應用程序。這需要設置一個基于Docker的Linux環境。首先&#xff0c;讓我們了解一下你的具體需求和環境&#xff1a;你有一個Qt項目&#xff08;看起來是醫學設備相關的設置程序&#xff09;目標平臺是ARM架構你希望在Windows …

linux常見故障系列文章 1-linux進程掛掉原因總結和排查思路

問題一 &#xff1a;運行時常見的進程崩潰原因 內存不足&#xff09; **0. 內存不足 內存不足&#xff08;OOM Killer&#xff09; 排查 OOM&#xff1a;free -h → dmesg → ps aux --sort-%mem 預防 OOM&#xff1a;限制關鍵進程內存、調整 OOM Killer 策略、增加 swap 長期優…

Spring Cloud Gateway 路由與過濾器實戰:轉發請求并添加自定義請求頭(最新版本)

前言 網關是什么?如果把你的系統比作一棟高端寫字樓,網關就是那位神通廣大的前臺小姐姐,笑容可掬地攔住不速之客,把貴賓引到豪華會議室,還會在你胸口貼上一枚醒目的“貴賓”標簽。它既懂禮數,又有原則,能過濾無效請求、轉發正確目標,還能在途中動點“小手腳”,比如加…

達夢數據庫慢SQL日志收集和分析

達夢數據庫慢SQL日志收集和分析 開啟SQL日志記錄 使用DMLOG工具分析SQLLOG DMLOG安裝配置 DMLOG分析日志 系統視圖V$LONG_EXEC_SQLS記錄了最近1000條執行時間超1s的sql。如果sql語句超長可能會被截斷,只能從sqllog里找完整的sql文本。 SELECT * FROM V$LONG_EXEC_SQLS ORDER …

一篇文章,帶你玩轉SparkCore

Spark Core 概念 前言 批處理&#xff08;有界數據&#xff09; ? 對靜態的、有限的數據集進行一次性處理&#xff0c;數據通常按固定周期&#xff08;如每小時、每天&#xff09;收集后統一計算。 特點&#xff1a; 高吞吐量&#xff0c;適合大規模數據。高延遲&#xff08;數…

VRRP技術

VRRP的概念及應用場景 VRRP&#xff08;虛擬路由冗余協議&#xff09;概念 VRRP&#xff08;Virtual Router Redundancy Protocol&#xff0c;虛擬路由冗余協議&#xff09;是一種路由容錯協議&#xff0c;用于在多個路由器之間提供網關冗余&#xff0c;確保當主路由器故障時&a…

表驅動法-靈活編程范式

表驅動法&#xff1a;從理論到實踐的靈活編程范式 一、為什么需要表驅動法&#xff1f; 在處理多分支邏輯&#xff08;如消息解析、命令分發&#xff09;時&#xff0c;傳統的 if-else 或 switch-case 存在明顯局限&#xff1a; 當分支數量龐大&#xff08;如成百上千條命令&am…

零基礎-動手學深度學習-10.2. 注意力匯聚:Nadaraya-Watson 核回歸

上節介紹了框架下的注意力機制的主要成分 圖10.1.3&#xff1a; 查詢&#xff08;自主提示&#xff09;和鍵&#xff08;非自主提示&#xff09;之間的交互形成了注意力匯聚&#xff1b; 注意力匯聚有選擇地聚合了值&#xff08;感官輸入&#xff09;以生成最終的輸出。 本節將…

nginx高新能web服務器

一、Nginx 概述和安裝 Nginx是免費的、開源的、高性能的HTTP和反向代理服務器、郵件代理服務器、以及TCP/UDP代理服務器。 Nginx 功能介紹 靜態的web資源服務器html&#xff0c;圖片&#xff0c;js&#xff0c;css&#xff0c;txt等靜態資源 http/https協議的反向代理 結合F…

Unity大型場景性能優化全攻略:PC與安卓端深度實踐 - 場景管理、渲染優化、資源調度 C#

本文將深入探討Unity在大型場景中的性能優化策略&#xff0c;涵蓋場景管理、渲染優化、資源調度等核心內容&#xff0c;并提供針對PC和安卓平臺的優化方案及實戰案例。 提示&#xff1a;內容純個人編寫&#xff0c;歡迎評論點贊。 文章目錄1. 大型場景性能挑戰1.1 性能瓶頸定位…

Java集合框架、Collection體系的單列集合

Java集合框架、Collection1. 認識Java集合框架及結構1.1 集合框架整體結構1.2 集合框架的核心作用2. Collection的兩大常用集合體系及各個系列集合的特點2.1 List系列集合&#xff08;有序、可重復&#xff09;2.2 Set系列集合&#xff08;無序、不可重復&#xff09;3. Collec…

HTML <picture> 元素:讓圖片根據設備 “智能切換” 的響應式方案

在響應式設計中&#xff0c;圖片適配是一個繞不開的難題&#xff1a;同一張高清圖片在大屏設備上清晰美觀&#xff0c;但在小屏手機上可能加載緩慢&#xff1b;而適合手機的小圖在桌面端又會模糊失真。傳統的解決方案往往需要用JavaScript判斷設備尺寸并動態替換圖片源&#xf…