Day 6:錯誤處理模式整理
學習目標
- 總結常見錯誤處理模式
- 建立「錯誤為值」的設計思維
- 練習分層錯誤處理
今日重點
常見錯誤處理模式
模式一:錯誤恢復(recover)
fn try_parse(input: &str) -> Result<i32, String> {
input.trim().parse::<i32>().map_err(|e| format!("Parse error: {}", e))
}
失敗時提供可讀訊息,讓呼叫端可 ds。retry 或給預設值。
模式二:錯誤傳播(propagate),用 ? 往上拋。
模式三:錯誤轉換(map_err / From)
把底層錯誤轉成上層語義錯誤(io::Error → AppError::Io)。
模式四:錯誤作為值(error as value)
enum RetryOutcome {
Success,
Retry,
Fail,
}
用列舉表達「可能要再試」的狀態,而不是直接 panic。
分層架構的錯誤
| 層級 | 錯誤型別 |
|---|---|
| 底層(library) | 具體錯誤(io::Error、自訂) |
| 中間層 | 用 From 轉成 domain 錯誤 |
| 頂層(main) | Box |
練習
use std::fs;
// 設計一個 3 層錯誤:驗證失敗 -> 讀檔失敗 -> 存入失敗
#[derive(Debug)]
enum ServiceError {
Invalid(String),
Io(std::io::Error),
}
impl From<std::io::Error> for ServiceError {
fn from(e: std::io::Error) -> Self { ServiceError::Io(e) }
}
fn save_text(text: &str, path: &str) -> Result<(), ServiceError> {
if text.trim().is_empty() {
return Err(ServiceError::Invalid("空文字".to_string()));
}
fs::write(path, text)?; // io::Error 自動轉
Ok(())
}
自我檢查
- 能列出 4 種常見錯誤模式
- 理解錯誤傳播、轉換、回復
- 能用「錯誤作為值」的列舉設計
- 懂分層架構的錯誤設計
深入連結
- The Book 第 9 章(全章)+ Rustonomicon error handling