應用程式運行的過程中,不免會有例外事件的錯誤發生,透過良好的設計來處理例外狀況與錯誤,能防止應用程式因此崩潰壞掉,並能讓使用者也可以有比較良好的體驗。
今天就用ASP.NET Core Web API 作為處理和自訂錯誤處理的範例。
在ASP.NET Core 3 應用程式的開發時期中提供了開發人員例外狀況頁面,這是一個非常實用的工具,可以取得例外狀況的詳細資訊與堆疊追蹤。它會使用 DeveloperExceptionPageMiddleware 從 HTTP pipeline捕獲同步和非同步例外狀況,並產生錯誤回應。
在APS.NET Core 專案範本中,都可以在Startup.Configure
看到下列程式碼
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
在專案範本中,開發時期都會預設為我們啟用開發人員例外狀況頁面,以下示範在開發時期使用Postman呼叫Web API,所回傳的錯誤格式
在一般的使用情況下,會收到純文字的錯誤堆疊(Stack)訊息。
只要在Request Headers中加入 Accept: text/html(如下圖所示),就可以看到完整的開發人員例外狀況頁面
透過HTML格式的回應讓錯誤訊息變得比較漂亮易閱讀。
在上面的範例中,如果是非開發環境下如果發生了例外事件,伺服器端就會直接報錯,而且不會回應任何資訊,如以下畫面
伺服器只會報500錯誤,但是在相對更需要穩定的正式環境下,這樣的錯誤是非常難以處理的,這時候就需要對非開發環境作出不同的例外處理。
我們可以透過ExcetionHanlder的 Middleware pipeline來進行非開發環境的例外處理
首先要在Startup.Configure
中作出以下改動
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/error");
}
透過UseExceptionHandler()將非開發環境的例外事件處理都引導至路由為 /error 的Action
接著建立一個ErrorController,並加入以下內容
[Route("api/[controller]")]
[ApiController]
public class ErrorController : ControllerBase
{
[Route("/error")]
public ActionResult Error() => Problem();
}
透過 [Route("/error")] 強制將Action的路由變成 /error
上述名為Error的Action會將RFC 7807格式的錯誤訊息回傳至用戶端
這樣便能為不同的環境設置不同的錯誤處理機制。
補充:在MVC的專案範本中,提供了錯誤頁面可供非開發環境下使用。
MVC中的Startup.Configure
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
備註:env.IsDevelopment()是從Properties/launchSettings.json取得的組態設定,後面會為組態設定做進一步的介紹。
上面的範例都是在介紹,當拋出錯誤的時候,應該如何顯示錯誤訊息,但是在一個穩定的應用程式中,不會什麼錯誤都直接拋出讓前端的使用者看到,因此針對例外處理的方式有幾點建議:
參考資料
MSDN-例外處理
處理 ASP.NET Core 中的錯誤