استثناهای کنترل نشده می توانند باعث سردرگمی و ناامیدی شوند. آنها را با فیلترهای استثنا پاک کنید.
فیلترهای استثنایی Nest.js راهی برای رهگیری و رسیدگی به استثناها در سطح جهانی یا بر اساس هر کنترلر ارائه می دهند.
آنها به شما اجازه می دهند منطق رسیدگی به خطا را متمرکز کنید، پاسخ های خطا را قالب بندی کنید و مدیریت خطا را در سراسر برنامه خود ارائه دهید. درباره فیلترهای استثنا و نحوه استفاده از آنها برای رسیدگی مناسب به خطاهای برنامه بیاموزید.
پیشفرض مدیریت خطا در Nest.js
بهطور پیشفرض، Nest.js دارای یک لایه استثنایی است که با هر استثنایی که کد برنامه شما از آن استفاده نمیکند، سروکار دارد.
هنگامی که یک خطای کنترل نشده در برنامه شما رخ می دهد، Nest.js آن را دریافت می کند و یک خطای سرور داخلی 500 را به مشتری برمی گرداند. JSON که Nest.js در این مورد برمی گرداند به شکل زیر است:
{
"statusCode": 500,
"message": "Internal server error"
}
اگر شی خطایی که کد شما پرتاب میکند حاوی statusCode و پیام باشد، Nest.js آن مقادیر را بهجای پاسخ پیشفرض برمیگرداند.
برای جلوگیری از این رفتار عمومی و ارسال پاسخ خطای معنادارتر به مشتری، باید با جدیت تمام خطاهایی را که ممکن است در برنامه شما رخ دهد رسیدگی کنید. میتوانید با استفاده از فیلترهای استثنایی داخلی یا سفارشی Nest.js به این هدف برسید.
ایجاد یک فیلتر استثنای سفارشی
برای نشان دادن فرآیند ایجاد یک فیلتر استثنای سفارشی، سعی کنید فیلتری ایجاد کنید که تمام استثناهای HTTP را مدیریت کند.
با فایلی به نام http.exception.ts شروع کنید و واردات زیر را به آن اضافه کنید:
import {
ExceptionFilter,
Catch,
ArgumentsHost,
HttpException,
} from '@nestjs/common';
import { Request, Response } from 'express';
این واردات اهداف زیر را دنبال می کند.
- ExceptionFilter: این رابطی است که اجرای یک فیلتر استثنا را توصیف می کند.
- Catch: این یک دکوراتور است که یک کلاس را به عنوان فیلتر استثنایی Nest علامت گذاری می کند.
- ArgumentsHost: این رابط روش هایی را برای بازیابی آرگومان های ارسال شده به یک handler ارائه می دهد. این به شما امکان میدهد زمینه اجرای مناسب (مانند HTTP، RPC یا WebSockets) را برای بازیابی آرگومانها انتخاب کنید.
- HttpException: این کلاسی است که استثنای اصلی Nest HTTP را تعریف می کند.
- Request & Response: اینها به ترتیب رابط های درخواست و پاسخ Express.js هستند.
در مرحله بعد، یک کلاس به نام HttpExceptionFilter ایجاد کنید که ExceptionFilter را پیاده سازی می کند. آن را با تزئین کننده Catch حاشیه نویسی کنید تا نشان دهید که HttpExceptions را مدیریت می کند:
@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 و فیلتر استثنای خود را وارد کنید. کلاس کنترلر خود را با decorator @UseFilters حاشیه نویسی کنید و نمونه ای از فیلتر استثنای خود را به عنوان آرگومان به دکوراتور ارسال کنید:
@Controller()
@UseFilters(new HttpExceptionFilter())
export class AppController {}
جایی که فیلتر خود را متصل می کنید، دامنه رسیدگی به خطا را تعیین می کند. فیلترهای محدود به کنترلر فقط به کنترلری که آن را به آن متصل کرده اید پاسخ می دهند و فیلترهای محدود به برنامه به کل برنامه پاسخ می دهند.
استفاده از استثناهای داخلی برای پرتاب خطاها
Nest.js کلاس های استثنای داخلی را ارائه می دهد که می توانید از آنها برای ایجاد خطا استفاده کنید.
به عنوان مثال، می توانید خطاهای کد وضعیت 404 را با کلاس NotFoundException ایجاد کنید:
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: یک استثنا پرتاب می کند که نشان دهنده یک درخواست بد با کد وضعیت 400 است. زمانی که درخواست مشتری نامعتبر یا نادرست است، می توانید از این استثنا استفاده کنید و سرور به دلیل خطای مشتری نمی تواند آن را پردازش کند. معمولاً به این معنی است که مشتری باید درخواست را تغییر دهد تا معتبر باشد.
- UnauthorizedException: یک استثنا را نشان می دهد که دسترسی غیرمجاز با کد وضعیت 401 را نشان می دهد. شما می توانید از این استثنا زمانی استفاده کنید که کاربری احراز هویت نشده باشد یا مجوزهای لازم برای دسترسی به یک منبع را نداشته باشد.
- ForbiddenException: یک استثنا را نشان می دهد که دسترسی ممنوع را با کد وضعیت 403 نشان می دهد. شما می توانید از این استثنا زمانی استفاده کنید که یک کاربر احراز هویت شده است اما مجاز به انجام یک عمل خاص نیست.
- RequestTimeoutException: یک استثنا پرتاب می کند که نشان می دهد زمان درخواست با کد وضعیت 408 به پایان رسیده است. شما می توانید از این استثنا زمانی استفاده کنید که یک سرور یک درخواست را خاتمه دهد زیرا پردازش آن خیلی طول کشیده است.
- ConflictException: یک استثنا پرتاب می کند که نشان دهنده تضاد با کد وضعیت 409 است. می توانید از این استثنا در جایی استفاده کنید که بین درخواست مشتری و وضعیت فعلی منبع تضاد وجود دارد، مانند زمانی که سعی می کنید منبعی را ایجاد کنید که از قبل وجود دارد.
- InternalServerErrorException: یک استثنا را نشان می دهد که خطای سرور داخلی با کد وضعیت 500 را نشان می دهد. می توانید از این استثنا استفاده کنید زمانی که یک خطای غیرمنتظره در سمت سرور رخ می دهد که نشان می دهد سرور به دلیل مشکل داخلی نمی تواند درخواست را انجام دهد.
بهترین روش ها برای مدیریت خطا در Nest.js
هنگام رسیدگی به خطاها در Nest.js، حتماً از فیلترهای استثنا استفاده کنید تا استثناها را در سطح جهانی یا به ازای هر کنترلر بگیرید و مدیریت کنید. همچنین می توانید فیلترهای سفارشی را برای انواع استثنا ایجاد کنید.
علاوه بر این، مطمئن شوید که از کلاس های استثنا داخلی مناسب برای ایجاد خطاهای مناسب و معنی دار استفاده می کنید. این روشها میتوانند قابلیت اطمینان برنامههای Nest.js شما را به میزان قابل توجهی بهبود بخشند.