(系列六).net8 全域性異常捕獲機制

陈逸子风發表於2024-10-12

說明

該文章是屬於OverallAuth2.0系列文章,每週更新一篇該系列文章(從0到1完成系統開發)。

該系統文章,我會盡量說的非常詳細,做到不管新手、老手都能看懂。

說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+視覺化流程管理系統。

友情提醒:本篇文章是屬於系列文章,看該文章前,建議先看之前文章,可以更好理解專案結構。

有興趣的朋友,請關注我吧(*^▽^*)。

關注我,學不會你來打我

為什麼要用全域性異常捕獲?

對於一個系統來說,全域性異常捕獲是必不可少的,它不僅可以把異常資訊精簡後反饋給使用者,還能幫助程式設計師減少解決問題的時間,以及記錄系統中任何一處發生異常的資訊。

你是否依然有以下苦惱?

你是否還在為怎麼記錄系統異常日誌而苦惱?

你是否還在為系統報錯位置和報錯資訊苦惱?

你是否還在每個介面處增加日誌記錄操作?

如果你有,那麼本篇文章正好可以解決你的難題。

什麼是全域性異常捕獲機制?

全域性異常捕獲,顧名思義就是系統無論在那個位置發生錯誤都會被捕獲,從而進行處理。

建立介面返回模型

建立一個介面返回模型:ReceiveStatus.cs

它的主要作用是把介面返回的資料、資訊推送給前端。

 /// <summary>
 /// 介面返回實體模型
 /// </summary>
 public class ReceiveStatus
 {
     /// <summary>
     /// 編碼
     /// </summary>
     public CodeStatuEnum code { get; set; }

     /// <summary>
     /// 資訊
     /// </summary>
     public string msg { get; set; }

     /// <summary>
     /// 是否成功
     /// </summary>
     public bool success { get; set; }

     /// <summary>
     /// 建構函式
     /// </summary>
     public ReceiveStatus()
     {
         code = CodeStatuEnum.Successful;
         success = true;
         msg = "操作成功";
     }
 }
 /// <summary>
 /// 介面返回結果集
 /// </summary>
 /// <typeparam name="T"></typeparam>
 public class ReceiveStatus<T> : ReceiveStatus
 {
     /// <summary>
     /// 資料
     /// </summary>
     public List<T> data { get; set; }

     /// <summary>
     /// 總數量
     /// </summary>
     public int total { get; set; }
 }
CodeStatuEnum.cs列舉值如下
 /// <summary>
 /// 程式碼狀態列舉
 /// </summary>
 public enum CodeStatuEnum
 {
     /// <summary>
     /// 操作成功
     /// </summary>
     Successful = 200,

     /// <summary>
     ///  警告
     /// </summary>
     Warning = 99991,

     /// <summary>
     /// 操作引發錯誤
     /// </summary>
     Error = 99992
 }

建立好介面返回模型後,我們建立一個異常幫助類,它的主要用途,是區分【系統異常】還是使用者自定義的【業務異常】。

/// <summary>
/// 異常幫助類
/// </summary>
public class ExceptionHelper
{
    /// <summary>
    /// 自定義異常(會寫入錯誤日誌表)
    /// </summary>
    /// <param name="msg"></param>
    public static void ThrowBusinessException(string msg)
    {
        throw new Exception(msg);
    }

    /// <summary>
    /// 自定義業務異常(不會寫入錯誤日誌表)
    /// </summary>
    /// <param name="msg">資訊資訊</param>
    /// <param name="codeStatu">異常狀態</param>
    /// <returns>返回結果集</returns>
    public static ReceiveStatus CustomException(string msg, CodeStatuEnum codeStatu = CodeStatuEnum.Warning)
    {
        ReceiveStatus receiveStatus = new();
        receiveStatus.code = codeStatu;
        receiveStatus.msg = msg;
        receiveStatus.success = false;
        return receiveStatus;
    }

}

/// <summary>
/// 異常幫助類(返回資料)
/// </summary>
/// <typeparam name="T"></typeparam>
public class ExceptionHelper<T> : ExceptionHelper
{
    /// <summary>
    /// 自定義業務異常(不會寫入錯誤日誌表)
    /// </summary>
    /// <param name="msg">資訊資訊</param>
    /// <param name="codeStatu">異常狀態</param>
    /// <returns>返回結果集</returns>
    public static ReceiveStatus<T> CustomExceptionData(string msg, CodeStatuEnum codeStatu = CodeStatuEnum.Warning)
    {
        ReceiveStatus<T> receiveStatus = new();
        receiveStatus.code = codeStatu;
        receiveStatus.msg = msg;
        receiveStatus.success = false;
        receiveStatus.data = new System.Collections.Generic.List<T>();
        return receiveStatus;
    }
}

建立全域性異常捕獲中介軟體

在wenApi啟動專案中建立一個類:ExceptionPlugIn.cs

它的主要作用就是捕獲系統中發生異常對程式碼和記錄異常日誌。

它需要繼承一個介面:IAsyncExceptionFilter

/// <summary>
/// 全域性異常捕獲中介軟體
/// </summary>
public class ExceptionPlugIn : IAsyncExceptionFilter
{
    /// <summary>
    /// 全域性異常捕獲介面
    /// </summary>
    /// <param name="context"></param>
    /// <returns></returns>
    public Task OnExceptionAsync(ExceptionContext context)
    {
        //異常資訊
        Exception ex = context.Exception;

        //異常位置
        var DisplayName = context.ActionDescriptor.DisplayName;

        //異常行號
        int lineNumber = 0;
        const string lineSearch = ":line ";
        var index = ex.StackTrace.LastIndexOf(lineSearch);
        if (index != -1)
        {
            var lineNumberText = ex.StackTrace.Substring(index + lineSearch.Length);
            lineNumber = Convert.ToInt32(lineNumberText.Substring(0, lineNumberText.IndexOf("\r\n")));
        }

        // 如果異常沒有被處理則進行處理
        if (context.ExceptionHandled == false)
        {
            string exceptionMsg = "錯誤位置:" + DisplayName + "\r\n" + "錯誤行號:" + lineNumber + "\r\n" + "錯誤資訊:" + ex.Message;
            // 定義返回型別
            var result = new ReceiveStatus<string>
            {
                code = CodeStatuEnum.Error,
                msg = "錯誤資訊:" + exceptionMsg,
                success = false,
            };
            context.Result = new ContentResult
            {
                // 返回狀態碼設定為200,表示
                StatusCode = StatusCodes.Status500InternalServerError,
                // 設定返回格式
                ContentType = "application/json;charset=utf-8",
                Content = JsonConvert.SerializeObject(result)
            };
            //記錄日誌

        }
        // 設定為true,表示異常已經被處理了
        context.ExceptionHandled = true;
        return Task.CompletedTask;
    }
}

可以在OnExceptionAsync方法中新增記錄日誌、異常型別、異常分析等程式碼。

新增到服務中

編寫好異常捕獲機制後,我們需要把該類新增到Program.cs的服務中

//自定義全域性異常處理
builder.Services.AddControllers(a =>
{
    a.Filters.Add(typeof(ExceptionPlugIn));
});

測試全域性異常捕獲機制

新增一個異常測試介面

執行測試

以上就是全域性異常捕獲機制,感興趣的可以下載專案,修改吧。

原始碼地址:https://gitee.com/yangguangchenjie/overall-auth2.0-web-api

預覽地址:http://139.155.137.144:8880/swagger/index.html

幫我Star,謝謝。

有興趣的朋友,請關注我微信公眾號吧(*^▽^*)。

關注我:一個全棧多端的寶藏博主,定時分享技術文章,不定時分享開源專案。關注我,帶你認識不一樣的程式世界

相關文章