Contents

วิธีใช้ตัวกรองข้อยกเว้น Nest.js เพื่อจัดการกับข้อผิดพลาด

ตัวกรองข้อยกเว้นของ Nest.js มีวิธีสกัดกั้นและจัดการข้อยกเว้นทั่วโลกหรือตามแต่ละตัวควบคุม

การรวมตรรกะการจัดการข้อผิดพลาดแบบรวมศูนย์ช่วยให้นักพัฒนาสามารถปรับปรุงกระบวนการของตนโดยการรวบรวมโค้ดที่เกี่ยวข้องกับข้อผิดพลาดทั้งหมดไว้ในที่เดียว วิธีการนี้ไม่เพียงทำให้การแก้ไขปัญหาง่ายขึ้น แต่ยังช่วยให้สามารถนำเสนอข้อความแสดงข้อผิดพลาดแก่ผู้ใช้ได้อย่างเป็นระเบียบมากขึ้น ด้วยการใช้ตัวกรองข้อยกเว้น นักพัฒนาสามารถจัดการข้อผิดพลาดที่เกิดขึ้นภายในแอปพลิเคชันได้อย่างมีประสิทธิภาพ โดยจัดให้มีกลไกการตอบสนองที่สอดคล้องกันซึ่งรับประกันความสอดคล้องกันทั่วทั้งระบบ

การจัดการข้อผิดพลาดเริ่มต้นใน Nest.js

Nest.js มีกลไกการจัดการข้อยกเว้นในตัวซึ่งดูแลข้อยกเว้นที่ไม่สามารถจัดการได้ซึ่งสร้างโดยโค้ดของแอปพลิเคชัน

เมื่อไม่มีใครสังเกตเห็นข้อยกเว้นในระหว่างรันไทม์ในแอปพลิเคชันของคุณที่พัฒนาโดยใช้เฟรมเวิร์ก Nest.js ระบบจะตอบสนองโดยอัตโนมัติด้วยรหัสสถานะ HTTP 500 Internal Server Error พร้อมด้วยเพย์โหลด JSON ที่กำหนดไว้ล่วงหน้าซึ่งมีข้อมูลเกี่ยวกับการเกิดข้อผิดพลาด รูปแบบนี้ออกแบบมาเพื่อให้นักพัฒนาใช้งานได้ง่ายซึ่งสามารถติดตามสาเหตุของปัญหาได้อย่างง่ายดายจากรายละเอียดที่ให้ไว้

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

หากโค้ดของคุณส่งออบเจ็กต์ข้อผิดพลาดมีทั้งรหัสสถานะและข้อความ Nest.js จะใช้ค่าเหล่านี้แทนที่จะให้การตอบสนองมาตรฐาน

เพื่อป้องกันการจัดการข้อผิดพลาดโดยทั่วไปและให้การตอบสนองที่มีข้อมูลมากขึ้นแก่ลูกค้า สิ่งสำคัญคือต้องจัดการข้อผิดพลาดที่อาจเกิดขึ้นทั้งหมดภายในแอปพลิเคชันของคุณอย่างระมัดระวัง ซึ่งสามารถทำได้โดยใช้ตัวกรองข้อยกเว้นที่มีอยู่แล้วของ Nest.js หรือสร้างตัวกรองแบบกำหนดเองที่เหมาะกับความต้องการเฉพาะของคุณ

การสร้างตัวกรองข้อยกเว้นแบบกำหนดเอง

เพื่อแสดงขั้นตอนในการพัฒนาตัวกรองข้อยกเว้นที่ออกแบบโดยเฉพาะ ให้พยายามสร้างตัวกรองที่สามารถจัดการกับข้อยกเว้น HTTP ทั้งหมดได้

พิจารณาเริ่มต้นด้วยเอกสารชื่อ “http.Exception.ts” และต่อมารวมข้อความสั่งการนำเข้าที่ตามมาไว้ภายใน:

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

import { Request, Response } from 'express';

การนำเข้าเหล่านี้มีวัตถุประสงค์ดังต่อไปนี้

ตัวกรองข้อยกเว้นที่นำมาใช้ผ่านอินเทอร์เฟซนี้ ทำหน้าที่ในการจับและจัดการข้อยกเว้นที่เกิดขึ้นระหว่างการทำงานของโปรแกรม

มัณฑนากร Catch บ่งบอกถึงการกำหนดคลาสให้เป็นกลไกการกรองข้อยกเว้นภายในกรอบงาน Nest

อินเทอร์เฟซ ArgumentsHost นำเสนอชุดวิธีการที่อำนวยความสะดวกในการรับข้อโต้แย้งที่ส่งไปยังตัวจัดการเฉพาะ ด้วยการใช้เฟรมเวิร์กนี้ เราสามารถเลือกบริบทการดำเนินการที่เหมาะสม เช่น HTTP, RPC หรือ WebSockets เพื่อแยกอาร์กิวเมนต์ดังกล่าวออกมา

HttpException แสดงถึงรากฐานของข้อยกเว้น Nest HTTP ทั้งหมด ซึ่งครอบคลุมโครงสร้างที่เป็นมาตรฐานสำหรับการจัดการข้อผิดพลาดในเว็บแอปพลิเคชัน

วัตถุคำขอและการตอบสนอง แบบแรกแสดงถึงคำขอของลูกค้าที่เข้ามา ในขณะที่แบบหลังใช้เพื่อส่งการตอบกลับคำขอเหล่านั้น

เพื่อที่จะใช้ตัวกรองข้อยกเว้นสำหรับการจัดการ HttpException ในแอปพลิเคชัน ASP.NET Core ของเรา เราสามารถสร้างคลาสใหม่ชื่อ HttpExceptionFilter คลาสนี้ควรสืบทอดมาจาก ExceptionFilterAttribute และใส่คำอธิบายประกอบด้วยแอตทริบิวต์ Catch เพื่อจัดการกับข้อยกเว้นประเภทนี้

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

จากนั้นเติมคลาสด้วยโค้ดนี้:

 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',
    });
}

การใช้งานปัจจุบันได้รับพารามิเตอร์คำขอและการตอบสนองจากอินสแตนซ์ ArgumentsHost และวิเคราะห์ข้อยกเว้นสำหรับข้อมูลที่เกี่ยวข้อง ผลลัพธ์คือการตอบกลับในรูปแบบ JSON ที่จัดระเบียบซึ่งมีเนื้อหาที่ให้ข้อมูลเกี่ยวกับข้อผิดพลาดที่ได้รับการส่งต่อไปยังผู้ใช้ปลายทาง

ตัวกรองข้อยกเว้นการเชื่อมโยง

คุณมีตัวเลือกในการใช้ตัวกรองข้อยกเว้นในระดับตัวควบคุมแต่ละตัวหรือทั่วทั้งแอปพลิเคชันของคุณ ขึ้นอยู่กับว่าสิ่งใดเหมาะสมกับความต้องการของคุณมากที่สุด

เพื่อที่จะใช้ตัวกรองข้อยกเว้นส่วนกลางในระดับสากล ให้เริ่มรวมตัวกรองข้อยกเว้นไว้ในไฟล์ main.ts หลักของคุณ จากนั้น นำเสนออินสแตนซ์ของตัวกรองข้อยกเว้นของคุณให้กับเมธอด 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();

ในการเชื่อมโยงข้อยกเว้นกับคอนโทรลเลอร์ จำเป็นต้องใช้มัณฑนากร “UseFilters” ร่วมกับตัวกรองข้อยกเว้นที่เกี่ยวข้อง กระบวนการนี้เกี่ยวข้องกับการนำเข้ามัณฑนากร"UseFilters"และตัวกรองข้อยกเว้นเฉพาะ ต่อจากนั้น คลาสคอนโทรลเลอร์จะต้องได้รับการใส่คำอธิบายประกอบโดยใช้มัณฑนากร “@UseFilters” ในขณะเดียวกันก็ส่งอินสแตนซ์ของตัวกรองข้อยกเว้นเป็นอาร์กิวเมนต์ไปยังมัณฑนากรด้วย

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

ตำแหน่งที่ใช้ตัวกรองจะกำหนดขอบเขตความสามารถในการจัดการข้อผิดพลาด หากตัวกรองเชื่อมโยงกับคอนโทรลเลอร์เฉพาะ ตัวกรองนั้นจะใช้กับคอนโทรลเลอร์นั้น ๆ เท่านั้น ในขณะที่ตัวกรองทั่วทั้งแอปพลิเคชันจะครอบคลุมแอปพลิเคชันทั้งหมด

การใช้ข้อยกเว้นในตัวเพื่อทำให้เกิดข้อผิดพลาด

Nest.js นำเสนอหมวดหมู่ข้อยกเว้นที่กำหนดไว้ล่วงหน้าหลายประเภทซึ่งสามารถใช้สำหรับการส่งข้อผิดพลาด ซึ่งได้รับการออกแบบมาเพื่อให้การจัดการข้อผิดพลาดง่ายขึ้น และปรับปรุงการพัฒนาแอปพลิเคชันโดยมอบแนวทางที่เป็นมาตรฐานในการจัดการข้อยกเว้นในลักษณะที่เป็นระบบ

อันที่จริง เราสามารถใช้คลาส NotFoundException เพื่อสร้างข้อผิดพลาดรหัสสถานะ 404 เพื่อตอบสนองต่อคำขอที่เซิร์ฟเวอร์ไม่สามารถตอบสนองได้ โดยทั่วไปจะใช้ข้อยกเว้นนี้เมื่อมีการพยายามเข้าถึงทรัพยากรหรือเพจที่ไม่มีอยู่บนเซิร์ฟเวอร์ ด้วยการโยนข้อยกเว้นนี้ เซิร์ฟเวอร์สามารถระบุให้ลูกค้าทราบว่าเนื้อหาที่ร้องขอไม่พร้อมใช้งาน และให้ข้อมูลเกี่ยวกับสาเหตุที่คำขอล้มเหลว

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

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

ส่วนของโค้ดที่กล่าวมาข้างต้นใช้นิพจน์แบบมีเงื่อนไขเพื่อตรวจสอบว่ามีผู้ใช้ที่ระบุอยู่หรือไม่ ในกรณีที่ไม่มีอยู่ จะทำให้เกิดข้อยกเว้น 404 โดยใช้คลาส NotFoundException และจัดเตรียมข้อความที่เกี่ยวข้องเป็นอาร์กิวเมนต์

คลาสข้อยกเว้นในตัวทั่วไป

หมวดหมู่ข้อยกเว้นที่กำหนดไว้ล่วงหน้าเพิ่มเติมจะครอบคลุมแต่ไม่จำกัดเฉพาะตัวอย่างต่อไปนี้

BadRequestException เป็นข้อยกเว้นพิเศษในการพัฒนาซอฟต์แวร์ที่แสดงถึงการตอบสนอง HTTP ด้วยรหัสสถานะ 400 ข้อยกเว้นนี้จะเกิดขึ้นเมื่อเซิร์ฟเวอร์ถือว่าคำขอของลูกค้าไม่ถูกต้องหรือมีรูปแบบที่ไม่เหมาะสม ทำให้ไม่สามารถประมวลผลได้ ความหมายหลักของข้อยกเว้นนี้คือ ลูกค้าจะต้องปรับเปลี่ยนคำขอของตนให้สอดคล้องเพื่อแก้ไขข้อผิดพลาดหรือความผิดปกติใดๆ

คลาส UnauthorizedException ส่งข้อยกเว้นที่ระบุถึงการเข้าถึงที่ไม่ได้รับอนุญาต พร้อมด้วยรหัสสถานะ HTTP 401 ข้อยกเว้นนี้อาจเกิดขึ้นในสถานการณ์ที่ผู้ใช้ไม่ได้รับการรับรองความถูกต้องหรือไม่มีสิทธิ์ที่จำเป็นเพื่อเข้าสู่ทรัพยากรเฉพาะ.

คลาส ForbiddenException แสดงถึงข้อยกเว้นที่บ่งบอกถึงการเข้าถึงที่ไม่ได้รับอนุญาต พร้อมด้วยรหัสสถานะ HTTP 403 ข้อยกเว้นนี้อาจเกิดขึ้นได้ในสถานการณ์ที่ผู้ใช้ได้รับการรับรองความถูกต้องสำเร็จ แต่ยังขาดสิทธิ์ที่จำเป็นในการดำเนินการบางอย่าง

RequestTimeoutException เป็นข้อยกเว้นที่ใช้ Java ซึ่งจะถูกส่งออกมาเมื่อคำขอเกินระยะเวลาที่กำหนด ส่งผลให้มีรหัสสถานะ HTTP เป็น 408 เซิร์ฟเวอร์อาจใช้ข้อยกเว้นนี้เพื่อยุติคำขอที่ใช้เวลานานกว่าที่คาดไว้ในการประมวลผล.

คลาส ConflictException แสดงถึงข้อยกเว้นที่เกิดขึ้นเนื่องจากข้อขัดแย้งในรหัสสถานะ 409 ข้อยกเว้นประเภทนี้อาจถูกส่งออกเมื่อคำขอของลูกค้าขัดแย้งกับสถานะปัจจุบันของทรัพยากรที่กำลังดำเนินการอยู่ เช่น ในขณะที่พยายาม สร้างทรัพยากรที่ได้สร้างไว้แล้ว

InternalServerErrorException เป็นข้อยกเว้นประเภทหนึ่งที่แสดงถึงข้อผิดพลาดที่ไม่คาดคิดที่เกิดขึ้นภายในโครงสร้างพื้นฐานฝั่งเซิร์ฟเวอร์ ส่งผลให้ไม่สามารถตอบสนองงานที่ร้องขอได้ ข้อยกเว้นเฉพาะนี้มีรหัสสถานะ HTTP ที่เกี่ยวข้องคือ 500 และควรใช้เมื่อใดก็ตามที่เกิดปัญหาที่ไม่คาดคิดบนฝั่งเซิร์ฟเวอร์ ซึ่งทำให้ไม่สามารถตอบสนองความต้องการของลูกค้าได้

แนวทางปฏิบัติที่ดีที่สุดสำหรับการจัดการข้อผิดพลาดใน Nest.js

เพื่อจัดการข้อผิดพลาดภายในแอปพลิเคชัน Nest.js อย่างมีประสิทธิภาพ สิ่งสำคัญคือต้องใช้ตัวกรองข้อยกเว้นที่จับข้อยกเว้นส่วนกลางหรือเฉพาะเจาะจงกับตัวควบคุมแต่ละตัว นอกจากนี้ เราอาจสร้างตัวกรองข้อยกเว้นแบบกำหนดเองซึ่งปรับให้เหมาะกับประเภทข้อผิดพลาดเฉพาะ

นอกจากนี้ การใช้คลาสข้อยกเว้นในตัวที่เหมาะสมสำหรับการส่งข้อความแสดงข้อผิดพลาดที่แม่นยำและสำคัญเป็นสิ่งสำคัญ แนวทางนี้มีส่วนช่วยอย่างมากในการเพิ่มความน่าเชื่อถือของแอปพลิเคชัน Nest.js ของคุณ