ASP.NET ProblemDetail 錯誤處理

之前筆記 ASP.NET 8 新增的錯誤處理 主要是想嘗試 ASP.NET 8 新增的錯誤處理功能,不過剛好官網文件 Microsoft Learn:Handle errors in ASP.NET Core 有提到其他錯誤處理做法,所以一併簡單紀錄,只是官網上的範例大多數情況下沒辦法滿足實際需求,所以今天就是進一步了解 ASP.NET 8 的 ProblemDetail 錯誤處理。

ProblemDetails 是 IETF RFC 7807 在 ASP.NET 中的實作,主要是為了標準化異常回應,讓 client 能夠更容易理解錯誤訊息

從 ASP.NET Core 2.2 開始,在 controller 加上 [ApiController] 並使用 ControllerBase 內建方法返回 HTTP 狀態代碼回應(如 Ok()BadRequest()),會自動將回應轉換為 ProblemDetails 格式

基本環境說明

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

使用方式

  1. 基本用法

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

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

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

    • 實際效果

      3problemdetail

      4problemdetail

  2. 客製 ProblemDetails

    以下三種方式

    • ProblemDetailsOptions.CustomizeProblemDetails:適用於增加固定值的情境

      在註冊呼叫 AddProblemDetails 時,使用 ProblemDetailsOptions.CustomizeProblemDetails 來客製化 ProblemDetails,以下透過增加 produceryowko 來做為範例

      • 實際效果

        1optionproblemdetail

        2optionproblemdetail

    • IProblemDetailsWriter

      • 實作 IProblemDetailsWriter 介面:Server500ProblemDetailWriter

        透過實作 IProblemDetailsWriter 介面來客製化 ProblemDetails,以下透過設定 title 為 IProblemDetailsWriter:An unexpected error occurred! 並增加 produceryowko 來做為範例

      • 註冊 IProblemDetailsWriter

        加入 builder.Services.AddTransient<IProblemDetailsWriter, Server500ProblemDetailWriter>(); (需要在 AddRazorPages, AddControllers, AddControllersWithViews or AddMvc 之前註冊),其他與基本用法一致

      • 實際效果

        3iproblemdetailswriter

        4iproblemdetailswriter

    • 在 middleware 中使用 IProblemDetailsService.WriteAsync:

      因為 middleware 的關係,無法直接攔 exception 或是在 middleware 中使用 try catch,我都紀錄一下做法

      • 官網做法:在處理 request 時在 context 中加入 feature

        5middleware

      • try catch 做法:在 middleware 中使用 try catch 來攔截 exception,需要自行將 status 改為 500,否則為是 200

        6200middleware

        7500middleware

心得

我自己覺得掌握度還是滿低的,沒有深入去理解背後的流程跟設計邏輯,所以在使用上就不清楚到底正確的用法是什麼,只是照著官網的範例來做,或是加加減減自己兜出個會動的範例,初步快速試試,有機會再找找看有沒有更多文件可以參考

參考資訊

  1. ASP.NET 8 新增的錯誤處理
  2. IETF RFC 7807
  3. Microsoft Learn:Handle errors in ASP.NET Core
  4. Using the ProblemDetails Class in ASP.NET Core Web API
  5. Microsoft Learn:ProblemDetails Class