NestJS — Node.js للمؤسسات

مرشّحات الاستثناءات ومعالجة الأخطاء

16 دقيقة الدرس 15 من 48

مرشّحات الاستثناءات ومعالجة الأخطاء

الأمور تسوء: سجلّ مفقود، مدخل سيّئ، طرف ثالث يتأخّر. لدى NestJS طبقة استثناءات مدمجة تحوّل الأخطاء المرميّة إلى استجابات HTTP سليمة — ومرشّحات الاستثناءات تتيح لك تخصيص شكل تلك الاستجابات بدقّة.

استثناءات HTTP المدمجة

بدل صياغة استجابات الأخطاء يدويًا، ارمِ أحد استثناءات NestJS المدمجة. يلتقطه الإطار ويُرسل رمز الحالة وجسم JSON الصحيحين:

import { NotFoundException, BadRequestException } from '@nestjs/common'; @Injectable() export class UsersService { findOne(id: number) { const user = this.users.find((u) => u.id === id); if (!user) { throw new NotFoundException(`User ${id} not found`); } return user; } }

الشائعة: BadRequestException (400) وUnauthorizedException (401) وForbiddenException (403) وNotFoundException (404) وConflictException (409) وInternalServerErrorException (500).

استثناء HttpException الأساسي

لحالة أو جسم مخصّص، ارمِ HttpException مباشرة:

import { HttpException, HttpStatus } from '@nestjs/common'; throw new HttpException('Custom message', HttpStatus.I_AM_A_TEAPOT);
ارمِ الأخطاء، لا تُعِدها. ما عليك سوى throw من أي مكان — خدمة أو أنبوب أو حارس. تلتقطه طبقة الاستثناءات عند الحدّ وتُنسّق الاستجابة. ويبقى معالجك نظيفًا.

كتابة مرشّح استثناءات

يأخذ مرشّح الاستثناءات التحكّم الكامل بالاستجابة للاستثناءات التي يلتقطها. زخرفه بـ @Catch() ونفّذ catch(exception, host):

import { ExceptionFilter, Catch, ArgumentsHost, HttpException } from '@nestjs/common'; @Catch(HttpException) export class HttpExceptionFilter implements ExceptionFilter { catch(exception: HttpException, host: ArgumentsHost) { const ctx = host.switchToHttp(); const response = ctx.getResponse(); const status = exception.getStatus(); response.status(status).json({ statusCode: status, timestamp: new Date().toISOString(), message: exception.message, }); } }

تحصُر @Catch(HttpException) المرشّح بنوع؛ بينما تلتقط @Catch() بلا وسيط كل شيء، وهي مفيدة كشبكة أمان عامة.

تطبيق المرشّحات

import { UseFilters } from '@nestjs/common'; @UseFilters(HttpExceptionFilter) // مستوى الدالّة أو المتحكّم @Get() findAll() {} // أو عامًّا: app.useGlobalFilters(new HttpExceptionFilter());
المرشّح العام هو مكان شكل الخطأ الموحّد. عرّف مرشّحًا واحدًا يُنسّق كل خطأ بالطريقة نفسها (حالة، طابع زمني، رسالة، معرّف طلب) وسجّله عامًّا — عندها يحصل العملاء على استجابات أخطاء متوقَّعة عبر الواجهة كلّها.
لا تُسرّب التفاصيل الداخلية. في الإنتاج، يجب أن يُخفي مرشّح الاستثناءات آثار التتبّع ورسائل الأخطاء الخام لأخطاء مستوى 500. سجّل الخطأ الحقيقي في الخادم، لكن أرسِل للعميل رسالة عامّة.

الخلاصة

ارمِ استثناءات مدمجة كـ NotFoundException (أو HttpException للحالات المخصّصة) ودَع طبقة الاستثناءات تُنسّق استجابة HTTP. للتحكّم الكامل، اكتب مرشّح استثناءات بـ @Catch() وcatch(exception, host)، ثم اربطه لكل مسار أو عامًّا. يمنح المرشّح العام واجهتك شكل خطأ واحدًا متّسقًا وآمنًا. بهذا تكتمل دورة حياة الطلب — وأخير هذه المرحلة: المُزخرِفات المخصّصة.