import { Request, Response, NextFunction, ErrorRequestHandler } from "express"; import { SchemaValidationError, SlonikError } from "slonik"; import { ApiError } from "../exceptions/api-error.js"; import { logger } from "../plugins/logger.js"; import { ZodError } from "zod"; import { UnexpectedError } from "#exceptions/unexpected-errors.js"; const globalErrorHandler: ErrorRequestHandler = ( err: unknown, // Тип ошибки здесь может быть широким, далее идут проверки instanceof req: Request, res: Response, next: NextFunction, ) => { if (!err) next(); // Формируем объект с деталями запроса для логов const requestDetails = { method: req.method, url: req.originalUrl, ip: req.ip, body: req.body, // Осторожно: может содержать чувствительные данные, логируйте по необходимости query: req.query, }; if (err instanceof ApiError) { logger.warn({ message: `API Error: ${err.message}`, err: err, request: requestDetails, }); res.status(err.status).json({ message: err.message, errors: err.errors }); return; } if (err instanceof UnexpectedError) { logger.error({ message: `Unexpected Error: ${err.message}`, err: err, request: requestDetails, }); res .status(err.status) .json({ message: "Внутренняя ошибка сервера (схема БД)" }); return; } if (err instanceof ZodError) { logger.error({ message: "Ошибка валидации ZOD на сервере", err: err, request: requestDetails, }); // TODO: Для клиента лучше отправлять обработанные ошибки, а не весь объект ZodError res.status(400).json({ message: "Ошибка валидации ZOD", errors: err.flatten().fieldErrors, }); return; } if (err instanceof SchemaValidationError) { logger.error({ message: "Ошибка несоответствия схемы БД (Slonik SchemaValidationError)", err: err, request: requestDetails, }); res.status(500).json({ message: "Внутренняя ошибка сервера (схема БД)" }); return; } if (err instanceof SlonikError) { logger.error({ message: "Ошибка запроса БД (SlonikError)", err: err, request: requestDetails, }); res.status(500).json({ message: "Внутренняя ошибка сервера (запрос БД)" }); return; } // Непредвиденная ошибка logger.error({ message: "Непредвиденная ошибка сервера", err: err, request: requestDetails, }); res.status(500).json({ message: "Произошла непредвиденная ошибка. Пожалуйста, попробуйте позже.", }); }; export default globalErrorHandler;