77 lines
2.4 KiB
JavaScript
77 lines
2.4 KiB
JavaScript
|
|
const config = require('../config');
|
|||
|
|
|
|||
|
|
// Централизованная обработка ошибок
|
|||
|
|
const errorHandler = (err, req, res, next) => {
|
|||
|
|
// Логирование ошибки
|
|||
|
|
console.error('❌ Ошибка:', {
|
|||
|
|
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) => {
|
|||
|
|
console.error('❌ Unhandled Rejection:', reason);
|
|||
|
|
// В production можно отправить уведомление
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
// Обработка необработанных исключений
|
|||
|
|
process.on('uncaughtException', (error) => {
|
|||
|
|
console.error('❌ Uncaught Exception:', error);
|
|||
|
|
// Graceful shutdown
|
|||
|
|
process.exit(1);
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
module.exports = {
|
|||
|
|
errorHandler,
|
|||
|
|
notFoundHandler
|
|||
|
|
};
|
|||
|
|
|