"use strict"; const multer = require("multer"); const { AppError } = require("../../errors"); /** * Единый middleware обработки ошибок приложения. * @param {import('../../logger').Logger} logger */ function errorHandler(logger) { // eslint-disable-next-line no-unused-vars return (err, req, res, next) => { const requestId = req.id || "req_unknown"; let status = 500; let message = "Внутренняя ошибка сервера."; let details = null; if (err instanceof AppError) { status = err.status; message = err.message; details = err.details || null; } else if (err instanceof multer.MulterError) { status = 400; if (err.code === "LIMIT_FILE_SIZE") { message = "Размер файла превышает допустимый лимит 25 МБ."; } else if (err.code === "LIMIT_FILE_COUNT") { message = "Превышено количество загружаемых файлов."; } else { message = `Ошибка загрузки файла: ${err.message}`; } details = { code: err.code, field: err.field }; } else if (err.type === "entity.too.large" || err.status === 413) { status = 413; message = "Размер переданных данных превышает лимит."; } else if (err instanceof SyntaxError && err.status === 400 && "body" in err) { status = 400; message = "Некорректный JSON в теле запроса."; } else if (err.status && typeof err.status === "number") { status = err.status; message = err.message || "Ошибка обработки запроса."; } const payload = { ok: false, error: message, requestId, }; if (details !== null && details !== undefined) { payload.details = details; } if (status >= 500) { logger.error("Необработанная ошибка сервера", { requestId, status, error: err.message, stack: err.stack, url: req.originalUrl, method: req.method, }); } else { logger.warn("Клиентская ошибка запроса", { requestId, status, error: message, details, url: req.originalUrl, method: req.method, }); } res.status(status).json(payload); }; } module.exports = { errorHandler, };