nakama/backend/middleware/errorHandler.js

78 lines
2.5 KiB
JavaScript
Raw Permalink Normal View History

2025-11-04 21:51:05 +00:00
const config = require('../config');
2025-11-10 20:13:22 +00:00
const { log } = require('./logger');
2025-11-04 21:51:05 +00:00
// Централизованная обработка ошибок
const errorHandler = (err, req, res, next) => {
// Логирование ошибки
2025-11-10 20:13:22 +00:00
log('error', 'Ошибка обработчика', {
2025-11-04 21:51:05 +00:00
message: err.message,
stack: config.isDevelopment() ? err.stack : undefined,
path: req.path,
method: req.method,
ip: req.ip,
user: req.user?.id || 'anonymous'
});
// Определение типа ошибки и статус кода
let statusCode = err.statusCode || err.status || 500;
let message = err.message || 'Внутренняя ошибка сервера';
// Обработка специфических ошибок
if (err.name === 'ValidationError') {
statusCode = 400;
message = 'Ошибка валидации данных';
} else if (err.name === 'CastError') {
statusCode = 400;
message = 'Неверный формат данных';
} else if (err.name === 'MongoError' && err.code === 11000) {
statusCode = 409;
message = 'Дубликат записи';
} else if (err.name === 'MulterError') {
statusCode = 400;
if (err.code === 'LIMIT_FILE_SIZE') {
message = 'Файл слишком большой';
} else if (err.code === 'LIMIT_FILE_COUNT') {
message = 'Слишком много файлов';
} else {
message = 'Ошибка загрузки файла';
}
} else if (err.name === 'AxiosError') {
statusCode = 502;
message = 'Ошибка внешнего сервиса';
}
// Отправка ответа
res.status(statusCode).json({
success: false,
error: message,
...(config.isDevelopment() && { stack: err.stack })
});
};
// Обработка 404
const notFoundHandler = (req, res, next) => {
res.status(404).json({
success: false,
error: 'Маршрут не найден'
});
};
// Обработка необработанных промисов
process.on('unhandledRejection', (reason, promise) => {
2025-11-10 20:13:22 +00:00
log('error', 'Unhandled Rejection', { reason: reason instanceof Error ? reason.message : reason });
2025-11-04 21:51:05 +00:00
// В production можно отправить уведомление
});
// Обработка необработанных исключений
process.on('uncaughtException', (error) => {
2025-11-10 20:13:22 +00:00
log('error', 'Uncaught Exception', { message: error.message, stack: error.stack });
2025-11-04 21:51:05 +00:00
// Graceful shutdown
process.exit(1);
});
module.exports = {
errorHandler,
notFoundHandler
};