// src/middlewares/error-handler.middleware.js // 에러 핸들러 미들웨어 const logger = require('../config/logger.config'); /** * 전역 에러 핸들러 */ module.exports = (err, req, res, _next) => { // 에러 로깅 logger.error('에러 발생:', { message: err.message, stack: err.stack, path: req.path, method: req.method, }); // Sequelize 유효성 검사 에러 if (err.name === 'SequelizeValidationError') { return res.status(400).json({ success: false, error: { code: 'VALIDATION_ERROR', message: '데이터 유효성 검사 실패', details: err.errors.map((e) => ({ field: e.path, message: e.message, })), }, }); } // Sequelize 고유 제약 조건 에러 if (err.name === 'SequelizeUniqueConstraintError') { return res.status(409).json({ success: false, error: { code: 'DUPLICATE_ENTRY', message: '중복된 데이터가 존재합니다.', details: err.errors.map((e) => ({ field: e.path, message: e.message, })), }, }); } // JWT 에러 if (err.name === 'JsonWebTokenError') { return res.status(401).json({ success: false, error: { code: 'INVALID_TOKEN', message: '유효하지 않은 토큰입니다.', }, }); } // 기본 에러 응답 const statusCode = err.statusCode || 500; const message = err.message || '서버 오류가 발생했습니다.'; // 프로덕션 환경에서는 상세 에러 숨김 const response = { success: false, error: { code: err.code || 'INTERNAL_ERROR', message: process.env.NODE_ENV === 'production' && statusCode === 500 ? '서버 오류가 발생했습니다.' : message, }, }; // 개발 환경에서는 스택 트레이스 포함 if (process.env.NODE_ENV === 'development') { response.error.stack = err.stack; } return res.status(statusCode).json(response); };