☕ NEW! 完成新手任務即可參加抽獎!LINE 星巴克禮券等你拿,名額有限!        🎉 推廣活動:邀請好友註冊 DevLearn,累積推薦抽 LINE 星巴克禮券! 活動詳情 →        🔥 活動期間 2026/4/1 - 5/31 |已有 0 人參加       
concept-backend 中級

例外處理哲學:該 catch 什麼?

原則:不要 catch 你不知道怎麼處理的例外

// ❌ 最糟糕的寫法:吞掉例外
try {
    DoSomething();
} catch (Exception) {
    // 什麼都不做 → 錯誤被隱藏,debug 時找不到原因
}

// ❌ 也很糟:catch 所有例外然後記 log 繼續跑
try {
    ProcessOrder(order);
} catch (Exception ex) {
    _logger.LogError(ex, "Error");
    // 然後呢?訂單沒處理成功但程式繼續跑?
}

// ✅ 好:只 catch 你知道怎麼處理的
try {
    var data = await httpClient.GetAsync(url);
} catch (HttpRequestException ex) {
    // 網路錯誤 → 回傳快取的資料
    return _cache.Get(cacheKey);
}
// 其他例外讓它自然往上拋

全域例外處理

// ASP.NET Core:用 Middleware 統一處理
app.UseExceptionHandler("/Error");

// 或自訂 Middleware
app.Use(async (context, next) => {
    try {
        await next();
    } catch (NotFoundException ex) {
        context.Response.StatusCode = 404;
        await context.Response.WriteAsJsonAsync(new { error = ex.Message });
    } catch (Exception ex) {
        _logger.LogError(ex, "Unhandled");
        context.Response.StatusCode = 500;
        await context.Response.WriteAsJsonAsync(new { error = "伺服器錯誤" });
    }
});

自訂例外 vs 回傳值

// 方式 1:拋例外(適合「不應該發生」的錯誤)
public User GetUser(int id) {
    return _db.Users.Find(id) ?? throw new NotFoundException($"User {id} not found");
}

// 方式 2:Result Pattern(適合「可預期的失敗」)
public Result<User> GetUser(int id) {
    var user = _db.Users.Find(id);
    return user != null ? Result.Ok(user) : Result.Fail("找不到使用者");
}
拋例外 Result Pattern
適合場景 程式錯誤、不預期的狀況 業務邏輯的「失敗」
效能 例外有效能成本 無額外成本
強制處理 不強制(可能忘了 catch) 強制(必須檢查 Result)

簡單記法:「找不到使用者」是業務邏輯(用 Result),「資料庫連不上」是基礎設施錯誤(用例外)。

💡 大家的想法 · 0

載入中...
💬 即時聊天室 🟢 0 人在線
😀 😎 🤓 💻 🎮 🎸 🔥
➕ 新問題
📋 我的工單
💬 LINE 社群
🔒
需要註冊才能使用此功能
註冊帳號即可解鎖測驗、遊戲、簽到、筆記下載等所有功能,完全免費!
免費註冊