Contents

Cách sử dụng bộ lọc ngoại lệ Nest.js để xử lý lỗi

Bộ lọc ngoại lệ của Nest.js cung cấp cách chặn và xử lý các ngoại lệ trên toàn cầu hoặc trên cơ sở từng bộ điều khiển.

Logic xử lý lỗi tập trung cho phép các nhà phát triển hợp lý hóa quy trình của họ bằng cách hợp nhất tất cả các mã liên quan đến lỗi vào một nơi. Cách tiếp cận này không chỉ đơn giản hóa việc khắc phục sự cố mà còn cho phép trình bày các thông báo lỗi có tổ chức hơn cho người dùng cuối. Bằng cách sử dụng các bộ lọc ngoại lệ, nhà phát triển có thể quản lý hiệu quả các lỗi xảy ra trong ứng dụng, cung cấp cơ chế phản hồi gắn kết để đảm bảo tính nhất quán trong toàn bộ hệ thống.

Xử lý lỗi mặc định trong Nest.js

Nest.js bao gồm một cơ chế xử lý ngoại lệ tích hợp sẵn để xử lý các ngoại lệ chưa được xử lý do mã của ứng dụng tạo ra.

Thật vậy, khi một ngoại lệ không được chú ý trong thời gian chạy trong ứng dụng của bạn được phát triển bằng khung Nest.js, hệ thống sẽ tự động phản hồi bằng mã trạng thái HTTP là 500 Lỗi máy chủ nội bộ cùng với tải trọng JSON được xác định trước chứa thông tin về việc xảy ra lỗi. Định dạng này được thiết kế để các nhà phát triển dễ dàng sử dụng, những người có thể dễ dàng truy tìm nguyên nhân của sự cố từ các chi tiết được cung cấp.

 {
  "statusCode": 500,
  "message": "Internal server error"
}

Nếu một đối tượng lỗi do mã của bạn gửi bao gồm cả mã trạng thái và thông báo, Nest.js sẽ sử dụng các giá trị này thay vì cung cấp phản hồi tiêu chuẩn.

Để ngăn chặn việc xử lý lỗi chung và thay vào đó cung cấp phản hồi nhiều thông tin hơn cho khách hàng, điều quan trọng là phải quản lý cẩn thận tất cả các lỗi tiềm ẩn trong ứng dụng của bạn. Điều này có thể được thực hiện bằng cách sử dụng các bộ lọc ngoại lệ có sẵn của Nest.js hoặc tạo các bộ lọc tùy chỉnh phù hợp với nhu cầu cụ thể của bạn.

Tạo bộ lọc ngoại lệ tùy chỉnh

Để minh họa quy trình phát triển bộ lọc ngoại lệ được thiết kế riêng, hãy thử xây dựng một bộ lọc có thể giải quyết tất cả các ngoại lệ HTTP.

Hãy cân nhắc việc bắt đầu bằng một tài liệu có tiêu đề “http.Exception.ts” và sau đó kết hợp các câu lệnh nhập tiếp theo trong đó:

 import {
  ExceptionFilter,
  Catch,
  ArgumentsHost,
  HttpException,
} from '@nestjs/common';

import { Request, Response } from 'express';

Những hàng nhập khẩu này phục vụ các mục đích sau.

Một bộ lọc ngoại lệ, được triển khai thông qua giao diện này, dùng để nắm bắt và xử lý các ngoại lệ xảy ra trong quá trình thực thi chương trình.

Trình trang trí Catch biểu thị việc chỉ định một lớp như một cơ chế lọc ngoại lệ trong khung Nest.

Giao diện ArgumentsHost trình bày một tập hợp các phương thức tạo điều kiện thuận lợi cho việc thu thập các đối số được truyền đến một trình xử lý cụ thể. Bằng cách sử dụng khung này, người ta có thể chọn ngữ cảnh thực thi thích hợp như HTTP, RPC hoặc WebSockets để trích xuất các đối số đã nói từ đó.

HttpException đại diện cho nền tảng của tất cả các ngoại lệ Nest HTTP, bao gồm cấu trúc được tiêu chuẩn hóa để xử lý lỗi trong ứng dụng web.

đối tượng yêu cầu và phản hồi. Cái trước đại diện cho các yêu cầu đến của khách hàng, trong khi cái sau được sử dụng để gửi lại phản hồi cho những yêu cầu đó.

Để triển khai bộ lọc ngoại lệ để xử lý HttpException s trong ứng dụng ASP.NET Core của chúng tôi, chúng tôi có thể tạo một lớp mới có tên HttpExceptionFilter. Lớp này phải kế thừa từ ExceptionFilterAttribution và được chú thích bằng thuộc tính Catch để xử lý các ngoại lệ thuộc loại này.

 @Catch(HttpException)
export class HttpExceptionFilter implements ExceptionFilter {}

Tiếp theo, điền vào lớp mã này:

 catch(exception: HttpException, host: ArgumentsHost) {
    // Get the response object from the arguments host
    const ctx = host.switchToHttp();
    const response = ctx.getResponse<Response>();

    // Get the request object from the arguments host
    const request = ctx.getRequest<Request>();

    // Get the status code from the exception
    const status = exception.getStatus();

    // Send a JSON response using the response object
    response.status(status).json({
      statusCode: status,
      timestamp: new Date().toISOString(),
      path: request.url,
      message:
        exception.message
       || exception.getResponse()['message']
       || 'Internal Server Error',
    });
}

Việc triển khai hiện tại thu thập các tham số yêu cầu và phản hồi từ phiên bản ArgumentsHost và phân tích các ngoại lệ đối với dữ liệu thích hợp. Kết quả là một câu trả lời có định dạng JSON có tổ chức chứa nội dung thông tin liên quan đến lỗi được chuyển tiếp đến người dùng cuối.

Bộ lọc ngoại lệ ràng buộc

Bạn có tùy chọn áp dụng bộ lọc ngoại lệ ở cấp độ bộ điều khiển riêng lẻ hoặc trong toàn bộ ứng dụng của mình, tùy thuộc vào điều gì phù hợp nhất với yêu cầu của bạn.

Để áp dụng chung bộ lọc ngoại lệ chung, ban đầu hãy kết hợp bộ lọc ngoại lệ trong tệp main.ts chính của bạn. Sau đó, trình bày bản khởi tạo bộ lọc ngoại lệ của bạn cho phương thức app.useGlobalFilters().

 // main.ts
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { HttpExceptionFilter } from './exception/http.exception';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);

  // Bind filter to the application
  app.useGlobalFilters(new HttpExceptionFilter());

  await app.listen(4050);
}

bootstrap();

Để liên kết một ngoại lệ với bộ điều khiển, cần phải sử dụng trình trang trí “UseFilters” cùng với bộ lọc ngoại lệ tương ứng. Quá trình này bao gồm việc nhập trình trang trí “UseFilters” và bộ lọc ngoại lệ cụ thể. Sau đó, lớp trình điều khiển phải được chú thích bằng cách sử dụng trình trang trí “@UseFilters”, đồng thời chuyển một phiên bản của bộ lọc ngoại lệ làm đối số cho trình trang trí.

 @Controller()
@UseFilters(new HttpExceptionFilter())
export class AppController {}

Vị trí áp dụng bộ lọc sẽ quyết định phạm vi khả năng xử lý lỗi của nó. Nếu một bộ lọc được liên kết với một bộ điều khiển cụ thể thì bộ lọc đó sẽ chỉ áp dụng cho bộ điều khiển cụ thể đó, trong khi bộ lọc toàn ứng dụng sẽ bao gồm toàn bộ ứng dụng.

Sử dụng ngoại lệ tích hợp để phát hiện lỗi

Nest.js cung cấp một loạt danh mục ngoại lệ được xác định trước có thể được sử dụng để đưa ra lỗi. Các danh mục này được thiết kế để đơn giản hóa việc xử lý lỗi và hợp lý hóa việc phát triển ứng dụng bằng cách cung cấp cách tiếp cận tiêu chuẩn hóa để quản lý các ngoại lệ một cách có tổ chức.

Thật vậy, người ta có thể sử dụng lớp NotFoundException để tạo ra lỗi mã trạng thái 404 nhằm đáp ứng các yêu cầu mà máy chủ không thể thực hiện được. Ngoại lệ này thường được sử dụng khi cố gắng truy cập tài nguyên hoặc trang không tồn tại trên máy chủ. Bằng cách ném ngoại lệ này, máy chủ có thể cho khách hàng biết rằng nội dung được yêu cầu không có sẵn và cung cấp thông tin về lý do yêu cầu không thành công.

   getUserById(id: number) {
    const user = users.find((user) => user.id === id);

    if (!user) {
      throw new NotFoundException({
        message: `User with id ${id} not found`,
      });
    }
  }

Đoạn mã trên sử dụng biểu thức điều kiện để xác minh xem người dùng được chỉ định có hiện diện hay không. Trong trường hợp vắng mặt, nó sẽ đưa ra ngoại lệ 404 bằng cách sử dụng lớp NotFoundException và cung cấp thông báo tương ứng làm đối số.

Các lớp ngoại lệ tích hợp phổ biến

Các danh mục ngoại lệ bổ sung được xác định trước bao gồm nhưng không giới hạn ở các ví dụ sau.

BadRequestException là một ngoại lệ chuyên biệt trong phát triển phần mềm đại diện cho phản hồi HTTP với mã trạng thái là 400. Ngoại lệ này được đưa ra khi yêu cầu của khách hàng được máy chủ cho là không hợp lệ hoặc được định dạng không đúng, khiến yêu cầu đó không thể được xử lý. Ý nghĩa chính của ngoại lệ này là khách hàng phải điều chỉnh yêu cầu của mình cho phù hợp để khắc phục mọi sai sót hoặc bất thường.

Lớp UnauthorizedException đưa ra một ngoại lệ biểu thị quyền truy cập trái phép, kèm theo mã trạng thái HTTP là 401. Ngoại lệ này có thể được ném ra trong trường hợp người dùng chưa được xác thực hoặc không có các đặc quyền cần thiết để có được quyền truy cập vào một tài nguyên cụ thể.

Lớp ForbiddenException đại diện cho một ngoại lệ biểu thị quyền truy cập trái phép, kèm theo mã trạng thái HTTP là 403. Ngoại lệ này có thể được đưa ra trong các tình huống trong đó người dùng đã được xác thực thành công nhưng thiếu các quyền cần thiết để thực hiện một thao tác cụ thể.

RequestTimeoutException là một ngoại lệ dựa trên Java được đưa ra khi một yêu cầu vượt quá giới hạn thời gian được chỉ định, dẫn đến mã trạng thái HTTP là 408. Ngoại lệ này có thể được máy chủ sử dụng để chấm dứt các yêu cầu mất nhiều thời gian hơn dự kiến ​​​​để xử lý.

Lớp Xung đột ngoại lệ đại diện cho một ngoại lệ xảy ra do xung đột trong mã trạng thái 409. Loại ngoại lệ này có thể được ném ra khi yêu cầu của khách hàng xung đột với trạng thái hiện tại của tài nguyên đang được vận hành, chẳng hạn như trong khi cố gắng tạo một tài nguyên đã được tạo.

InternalServerErrorException là một loại ngoại lệ thể hiện một lỗi không lường trước xảy ra trong cơ sở hạ tầng phía máy chủ, dẫn đến việc không thể đáp ứng nhiệm vụ được yêu cầu. Ngoại lệ cụ thể này có mã trạng thái HTTP liên quan là 500 và nên được sử dụng bất cứ khi nào có sự cố không mong muốn phát sinh ở phía máy chủ khiến nó không thể đáp ứng nhu cầu của khách hàng.

Các phương pháp hay nhất để xử lý lỗi trong Nest.js

Để quản lý hiệu quả các lỗi trong ứng dụng Nest.js, điều quan trọng là phải sử dụng các bộ lọc ngoại lệ để nắm bắt các ngoại lệ chung hoặc các bộ lọc dành riêng cho từng bộ điều khiển riêng lẻ. Ngoài ra, người ta có thể thiết lập các bộ lọc ngoại lệ tùy chỉnh phù hợp với các loại lỗi cụ thể.

Hơn nữa, điều quan trọng là phải sử dụng các lớp ngoại lệ sẵn có phù hợp để đưa ra các thông báo lỗi chính xác và nghiêm trọng. Cách tiếp cận này góp phần đáng kể vào việc nâng cao độ tin cậy của các ứng dụng Nest.js của bạn.