- vừa được xem lúc

Xử lý ngoại lệ một cách "tinh tế" trong NET 8

0 0 12

Người đăng: Hoàng Linh

Theo Viblo Asia

Exception - Ngoại lệ là gì ?

Một ngoại lệ là một tình huống bất thường hoặc không mong muốn xảy ra trong khi một chương trình đang thực thi, như truy cập một tệp không tồn tại, kết nối mạng bị ngắt, hoặc một lỗi logic trong chương trình. Trong .NET, "Exception" là một lớp cơ sở cho tất cả các loại ngoại lệ (exceptions). Lớp Exception là một phần của namespace System và cung cấp cơ sở cho việc xử lý các lỗi trong .NET thông qua cơ chế try - catch các khối lệnh.

Trước đây mình đã làm như thế nào?

Thông thường, trong một dự án Net MVC hay Net API, khi cần xử lý ngoại lệ chúng ta sẽ thực hiện theo cách cơ sở sau

  • Tạo một kiểu Exception của riêng chúng ta (nếu muốn)
  • Tạo một lớp ExceptionHandler để xử lý ngoại lệ theo logic của chúng ta
  • Tạo một middleware để handle ngoại lệ trong luồng chạy
  • Ném ngoại lệ đã tạo ở phần trên cho handler xử lý

Ví dụ: Lớp ApiException - kế thừa từ lớp Exception, đây đại diện cho những ngoại lệ xảy ra khi thực hiện truy vấn API

public class ApiException : Exception
{ private HttpStatusCode _httpStatusCode; public HttpStatusCode StatusCode { get => _httpStatusCode; } public ApiException() : base() { } public ApiException(string message, HttpStatusCode statusCode = HttpStatusCode.BadRequest) : base(message) { _httpStatusCode = statusCode; }
}

Lớp này sẽ nhận tham số đầu vào là một chuỗi thông báo lỗi và một mã HttpStatusCode trả về dựa vào lỗi (BadRequest, NotFound....)

Xây dựng lớp ExceptionHandlerMiddleware

public class ExceptionHandlerMiddleware
{ private readonly RequestDelegate _next; public ExceptionHandlerMiddleware(RequestDelegate next) { _next = next; } public async Task Invoke(HttpContext context) { try { await _next(context); } catch (Exception error) { var response = context.Response; response.ContentType = "application/json"; var responseModel = new { Message = error?.Message, Details = error?.InnerException?.Message }; switch (error) { case ApiException e: response.StatusCode = (int)e.StatusCode; break; default: response.StatusCode = (int)HttpStatusCode.InternalServerError; break; } var result = JsonConvert.SerializeObject(responseModel); await response.WriteAsync(result); } }
}

Lớp này sẽ đại diện cho 1 middleware xử lý Exception nếu có

Đăng ký middleware

app.UseMiddleware<ExceptionHandlerMiddleware>();

Và cuối cùng, trong API, bất cứ lúc nào cần xử lý ngoại lệ, ta cũng có thể ném nó ra

if (user is null) throw new ApiException("User is null", HttpStatusCode.BadRequest);

Trên đây là cách xử lý đơn thuần xưa nay chúng ta - hay ít nhất mình và dự án mình đang áp dụng, bây giờ thử với cách tinh tế hơn nhé !

"Đổi gió" với IExceptionHandler

IExceptionHandler là một interface định nghĩa một hợp đồng cho việc xử lý ngoại lệ. Interface này chủ yếu liên quan đến mô hình xử lý ngoại lệ tập trung thông qua middleware, giúp quản lý cách các ngoại lệ được xử lý trong ứng dụng.

Cách hoạt động: IExceptionHandler là một interface để xử lý các ngoại lệ trong các ứng dụng ASP.NET Core. Các thực thi IExceptionHandler được sử dụng bởi middleware xử lý ngoại lệ. Bằng cách tạo một lớp implement interface này, chúng ta sẽ thay thế việc sử dụng middleware ở cách trên.

Vẫn giữ mã nguồn lớp ApiException như ở trên

Tạo lớp ExceptionHandler implement IExceptionHandler

public class ExceptionHandler : IExceptionHandler
{ public async ValueTask<bool> TryHandleAsync(HttpContext httpContext, Exception exception, CancellationToken cancellationToken) { var response = exception switch { ApiException apiEx => new ProblemDetails { Status = (int)apiEx.StatusCode, Type = apiEx.GetType().Name, Title = apiEx.Message, Detail = apiEx.Message, Instance = $"{httpContext.Request.Method} {httpContext.Request.Path}" }, _ => new ProblemDetails { Status = StatusCodes.Status500InternalServerError, Type = exception.GetType().Name, Title = "Internal server error", Detail = "Internal server error", Instance = $"{httpContext.Request.Method} {httpContext.Request.Path}" } }; await httpContext.Response.WriteAsJsonAsync(response); return true; }
}

Đăng ký ExceptionHandler ở Program.cs hoặc ở nơi bạn đăng ký các DI

builder.Services.AddExceptionHandler<ExceptionHandler>();
builder.Services.AddProblemDetails();
...
**app.UseExceptionHandler(opt => { });** // Dòng này sẽ giúp chúng ta handle tương tự middleware app.MapGet("/weatherforecast", () =>
{ throw new ApiException("This is my exception", System.Net.HttpStatusCode.InternalServerError); // ví dụ ném 1 exception
});

Kết quả:

Tổng kết

IExceptionHandler là một cách mới để triển khai handle Exception trong ứng dụng ASP.NET Core, nó giúp chúng ta đơn giản hóa và dễ quản lý các Exception, việc xử lý ngoại lệ lúc này có thể xử lý ở toàn bộ chương trình, thật đơn giản ^^.

Bình luận

Bài viết tương tự

- vừa được xem lúc

Các loại tham chiếu Nullable trong C# (Phần 1)

1. Giới thiệu. C# 8.0 giới thiệu kiểu tham chiếu nullable và kiểu tham chiếu non-nullable cho phép bạn đưa ra các lựa chọn quan trọng về thuộc tính cho các biến kiểu tham chiếu:.

0 0 52

- vừa được xem lúc

Command pattern qua ví dụ !

Command pattern là gì . Command pattern khá phổ biến trong C #, đặc biệt khi chúng ta muốn trì hoãn hoặc xếp hàng đợi việc thực hiện một yêu cầu hoặc khi chúng ta muốn theo dõi các hoạt động. Hơn nữa, chúng ta có thể hoàn tác tác chúng. .

0 0 192

- vừa được xem lúc

Hiểu Liskov Substitution Principle qua ví dụ !

Liskov Substitution Principle là gì . Nguyên tắc đóng mở xác đinh rằng các instance của lớp con có thể thay thế được instance lớp cha mà vẫn đảm bảo tính đúng đắn của chương trình.

0 0 36

- vừa được xem lúc

Creating custom Controls Wpf

Introduction. Wpf/winforms provides various controls like Buttons, Textbox, TextBlock, Labels etc.

0 0 55

- vừa được xem lúc

[P1] Chọn công nghệ nào để xây dựng website?

Hiện nay nhu cầu phát triển website, app tăng rất cao do xu hướng "số hóa 4.0" trong và ngoài nước.

0 0 85

- vừa được xem lúc

Kiểu dữ liệu trong C#

Dẫn nhập. Ở bài BIẾN TRONG C# chúng ta đã tìm hiểu về biến và có một thành phần không thể thiếu khi khai báo biến – Đó là kiểu dữ liệu.

0 0 36