ASP.NET 8 新增的錯誤處理

ASP.NET Core 問市時提供了 Middleware 的做法:可以透過建立不同元件用做 pipeline 處理請求,讓 log、authentication、authorization、error handling 等功能可以將處理邏輯分離,不用與商業邏輯混在一起,其中 error handling 在使用 middleware 方式實作全域 exception handling 後不僅有更高的彈性,程式碼也更加簡潔

最近團隊專案陸續升級到 ASP.NET Core 8,發現官網在 error handling 的方式有不同做法,所以今天就來體驗看看新的方式

基本環境說明

  • macOS Sonoma 14.5 (Apple M2 Pro)
  • OrbStack 1.6.3 (17138)
  • .NET SDK 8.0.101
  • JetBrains Rider 2024.1.4

ASP.NET 的錯誤處理

  1. 使用 middleware (傳統做法;ASP.NET 8 也能用)

    • 建立 middleware 來處理錯誤

    • 在 Programs.cs 使用 middleware

      加上 app.UseMiddleware<ExceptionMiddleware>();

    • 實際效果

      1middleware

      2middleware

  2. 使用 Problem details (我看文件從 ASP.NET 2.1 開始就有 @@“)

    • 在註冊呼叫 AddProblemDetails 以下的 middleware 會連帶產生 ProblemDetails 的 http response

      • ExceptionHandlerMiddleware:會在未定義自訂處理常式時產生問題詳細資料回應。
      • StatusCodePagesMiddleware:預設會產生問題詳細資料回應。
      • DeveloperExceptionPageMiddleware:在 Accept 要求 HTTP 標頭不包含 text/html 時,在開發過程中產生問題詳細資料回應。
    • 在 Programs.cs 註冊使用

      加上 builder.Services.AddProblemDetails();app.UseExceptionHandler();

    • 實際效果

      3problemdetail

      4problemdetail

  3. 使用 IExceptionHandler (ASP.NET 8 新增)

    • 建立 ExceptionHandler 來處理錯誤

    • 在 Programs.cs 註冊使用

      加上 builder.Services.AddExceptionHandler<GlobalExceptionHandle>();app.UseExceptionHandler("/Error");

    • 實際效果

      5iexceptionhandler

      6iexceptionhandler

心得

  1. IExceptionHandler 的確是更加符合意圖,但以程式碼來看我個人覺得 middleware 為簡潔 (一行 app.UseMiddleware 就搞定),初步看來應該是為了避開 exception 的昂貴成本
  2. IExceptionHandler 有其彈性跟配套:IExceptionHandler 回傳 true/false 來判斷是否處理錯誤,並且可以透過 app.UseExceptionHandler("/Error"); 來指定處理錯誤的路由,但目前還沒想到實際應用的場景
  3. IExceptionHandler 目前還沒辦法單獨存在,一定會搭配 Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware 造成 log 會是成對出現,目前僅能透過 config 關閉 Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware 的 log 輸出

參考資訊

  1. Microsoft Learn:Handle errors in ASP.NET Core
  2. Why does ASP.NET Core log an unhandled exception when using a global exception handler?
  3. Global Exception Handling in ASP.NET Core - IExceptionHandler in .NET 8 [Recommended]
  4. Handling Errors with IExceptionHandler in ASP.NET Core 8.0
  5. Global Error Handling in ASP.NET Core 8
  6. The new way of Error Handling in .Net 8