使用aop(肉夾饃)為BlazorServer實現統一例外處理

2023-10-24 12:01:51

背景

使用者做一個操作往往對應一個方法的執行,而方法內部會呼叫別的方法,內部可能又會呼叫別的方法,從而形成一個呼叫鏈。我們一般是在最頂層的方法去加try,而不是呼叫鏈的每一層都去加try。

在web開發中,使用者的一個操作通常對應一個http請求,常見的mvc中一個controller的action會來執行這個處理。由於asp.net core是基於中介軟體管道的,很常見的方式就是定義一個「例外處理中介軟體」,它用try包住後續中介軟體的執行,在catch中捕獲異常,記錄紀錄檔,並返回一個統一的異常json結構返回給呼叫方。
一般我們會認為「全域性例外處理中介軟體」是一個兜底的方式,我們仍然應該在action中去try,因為那是具體業務邏輯處理的起點,不過我覺得木有必要,完全可以定義一個UserFriendlyException代表業務邏輯異常,而系統預設的Exception認為是系統級異常,在action的呼叫鏈中,不需要try,只是發現不滿足業務規則時: throw new UserFriendlyException 即可,而其它系統異常我們完全可以不考慮,最後在「全域性例外處理中介軟體」中判斷異常型別,若是UserFriendlyException則直接返回ex.Message給前端,不用做紀錄檔記錄;系統級異常則應該記錄異常堆疊紀錄檔,並返回一個友好的異常訊息給前端。

Blazor server中的預設例外處理及其問題

在blazor server中,首次請求後伺服器端和瀏覽器建立了長連線websocket,後續的瀏覽器和伺服器端的互動沒有類似http這種請求響應了,那在哪裡做全域性異常攔截呢?

blazor中提供了ErrorBoundary元件,基本格式如下:

<ErrorBoundary @ref="errorBoundary">
    <ChildContent>
        @Body
    </ChildContent>
    <ErrorContent>
        <p class="errorUI">