خطای zod را به پاسخ خطای قابل خواندن تبدیل کنید

خطای اعتبار سنجی zod را به شیء پیام کلیدی قابل خواندن FE در NestJS تبدیل کنید
نسخه اندونزیایی
https://abdulghofurme.github.io/posts/transform-zod-error-into-readable-error-response
چشم انداز
به عنوان یک مهندس فرانت اند،
من گهگاه با خطاهای اعتبارسنجی مواجه شده ام که چنین هستند کمتر آسان برای پردازش
خب من متخصص نیستم
اما به نظر من، اگر خطاهای اعتبار سنجی دریافتی راحت تر قابل رسیدگی باشد، بهتر است.
هدف
برای تبدیل خطاهای اعتبار سنجی Zod به این صورت:
{
"issues": [
{
"code": "too_small",
"minimum": 3,
"type": "string",
"inclusive": true,
"exact": false,
"message": "The category name must be at least 3 characters long",
"path": ["name"]
}
],
"name": "ZodError"
}
به یک پاسخ خطا در فرمت پیام key: مانند این:
{
"name": "The category name must be at least 3 characters long"
}
با key: message
فرمت بالا،
فکر می کنم خواندن و پردازش آن آسان تر است.
بار دیگر،
این بدان معنا نیست که قالب اول دشوار است. البته، می توان آن را پردازش کرد، اما نیاز به یک مرحله اضافی برای استخراج پیام های خطا از هر فیلد ورودی دارد.
کد
ما از یک استفاده خواهیم کرد فیلتر خطا/استثنا،
یک رویکرد استاندارد برای رسیدگی به خطاها مرکزی.
با این دستور می توانید فیلتر را ایجاد کنید:
nest g f error
# nest generate filter [filter_name]
در اینجا پیاده سازی است:
// ./error/error.filter.ts
import { ArgumentsHost, Catch, ExceptionFilter, HttpException, HttpStatus } from "@nestjs/common";
import { Response } from "express";
import { TWebResponse } from "src/model/web.model";
import { ZodError, ZodIssue } from "zod";
@Catch()
export class ErrorFilter<T> implements ExceptionFilter {
zodErrorToKeyedObject(error: ZodError): Record<string, string> {
return error.errors.reduce(
(acc, issue) => {
const key = issue.path.join(".");
acc[key] = issue.message;
return acc;
},
{} as Record<string, string>,
);
}
catch(exception: any, host: ArgumentsHost) {
const response: Response = host.switchToHttp().getResponse();
let result: {
status: HttpStatus;
json: TWebResponse;
};
if (exception instanceof HttpException) {
result = {
status: exception.getStatus(),
json: {
message: exception?.message,
},
};
} else if (exception instanceof ZodError) {
result = {
status: HttpStatus.BAD_REQUEST,
json: {
message: "Validation error",
errors: this.zodErrorToKeyedObject(exception),
},
};
} else {
result = {
status: HttpStatus.INTERNAL_SERVER_ERROR,
json: {
message: exception?.message,
},
};
}
response.status(result.status).json(result.json);
}
}
سپس فیلتر را روی برنامه خود اعمال کنید:
// app/global module
...
import { APP_FILTER } from '@nestjs/core';
import { ErrorFilter } from './error/error.filter';
...
@Module({
...
providers: [
...
{
provide: APP_FILTER,
useClass: ErrorFilter,
},
],
...
})
توضیح
HTTPEexception
...
if (exception instanceof HttpException) {
result = {
status: exception.getStatus(),
json: {
message: exception?.message,
},
};
}
...
HttpException را مدیریت می کند و آن را فوروارد می کند، به طوری که:
...
throw new HttpException(
'Category not found',
HttpStatus.NOT_FOUND,
);
...
این پاسخ را برمی گرداند:
{
"status": 404,
"data": {
"message": "Category not found"
}
}
ZodError
...
else if (exception instanceof ZodError) {
result = {
status: HttpStatus.BAD_REQUEST,
json: {
message: 'Validation error',
errors: this.zodErrorToKeyedObject(exception),
},
};
}
...
ZodError را می گیرد و روش:
...
zodErrorToKeyedObject(error: ZodError): Record<string, string> {
return error.errors.reduce(
(acc, issue) => {
const key = issue.path.join('.');
acc[key] = issue.message;
return acc;
},
{} as Record<string, string>,
);
}
...
ZodError را مطابق هدف ما به یک شیء خطای پیام تبدیل می کند.
این منجر به پاسخی مانند این می شود:
{
"status": 400,
"data": {
"message": "Validation error",
"errors": {
"name": "Field-specific error message"
}
}
}
دیگر
...
else {
result = {
status: HttpStatus.INTERNAL_SERVER_ERROR,
json: {
message: exception?.message,
},
};
}
...
هر گونه خطای دیگر را کنترل می کند و یک خطای سرور داخلی (500) را برمی گرداند.
نتیجه گیری
من معتقدم هر کسی نظرات و معیارهای خود را دارد.
با این حال، از دیدگاه noob FE،
خطاهای اعتبارسنجی اگر در کلید باشند راحت تر قابل رسیدگی هستند: قالب شیء پیام،
به آنها اجازه می دهد مستقیماً برای هر فیلد ورودی استخراج و نمایش داده شوند.
گفته می شود، اگر تیم از قبل استاندارد متفاوتی داشته باشد،
حتما بپذیرید، سوال بپرسید و به خوبی درباره آن بحث کنید.
شاید دلایل بهتری پشت آن باشد.
با خیال راحت سایر ملاحظات را به اشتراک بگذارید. 😉