Some checks failed
SonarQube Analysis / SonarQube Scan (push) Has been cancelled
- H/F/I/O SS304/GRAPHITE/CS/CS 패턴에서 4개 구성요소 모두 표시 - 기존 SS304 + GRAPHITE → SS304/GRAPHITE/CS/CS로 완전한 구성 표시 - 외부링/필러/내부링/추가구성 모든 정보 포함 - 구매수량 계산 모달에서 정확한 재질 정보 확인 가능
140 lines
4.5 KiB
Python
140 lines
4.5 KiB
Python
"""
|
|
에러 처리 유틸리티
|
|
표준화된 에러 응답 및 예외 처리
|
|
"""
|
|
from fastapi import HTTPException, Request
|
|
from fastapi.responses import JSONResponse
|
|
from fastapi.exceptions import RequestValidationError
|
|
from sqlalchemy.exc import SQLAlchemyError
|
|
from typing import Dict, Any
|
|
import traceback
|
|
|
|
from .logger import get_logger
|
|
|
|
logger = get_logger(__name__)
|
|
|
|
|
|
class TKMPException(Exception):
|
|
"""TK-MP 프로젝트 커스텀 예외"""
|
|
|
|
def __init__(self, message: str, error_code: str = "TKMP_ERROR", status_code: int = 500):
|
|
self.message = message
|
|
self.error_code = error_code
|
|
self.status_code = status_code
|
|
super().__init__(self.message)
|
|
|
|
|
|
class ErrorResponse:
|
|
"""표준화된 에러 응답 생성기"""
|
|
|
|
@staticmethod
|
|
def create_error_response(
|
|
message: str,
|
|
error_code: str = "INTERNAL_ERROR",
|
|
status_code: int = 500,
|
|
details: Dict[str, Any] = None
|
|
) -> Dict[str, Any]:
|
|
"""표준화된 에러 응답 생성"""
|
|
response = {
|
|
"success": False,
|
|
"error": {
|
|
"code": error_code,
|
|
"message": message,
|
|
"timestamp": "2025-01-01T00:00:00Z" # 실제로는 datetime.utcnow().isoformat()
|
|
}
|
|
}
|
|
|
|
if details:
|
|
response["error"]["details"] = details
|
|
|
|
return response
|
|
|
|
@staticmethod
|
|
def validation_error_response(errors: list) -> Dict[str, Any]:
|
|
"""검증 에러 응답"""
|
|
return ErrorResponse.create_error_response(
|
|
message="입력 데이터 검증에 실패했습니다.",
|
|
error_code="VALIDATION_ERROR",
|
|
status_code=422,
|
|
details={"validation_errors": errors}
|
|
)
|
|
|
|
@staticmethod
|
|
def database_error_response(error: str) -> Dict[str, Any]:
|
|
"""데이터베이스 에러 응답"""
|
|
return ErrorResponse.create_error_response(
|
|
message="데이터베이스 작업 중 오류가 발생했습니다.",
|
|
error_code="DATABASE_ERROR",
|
|
status_code=500,
|
|
details={"db_error": error}
|
|
)
|
|
|
|
@staticmethod
|
|
def file_error_response(error: str) -> Dict[str, Any]:
|
|
"""파일 처리 에러 응답"""
|
|
return ErrorResponse.create_error_response(
|
|
message="파일 처리 중 오류가 발생했습니다.",
|
|
error_code="FILE_ERROR",
|
|
status_code=400,
|
|
details={"file_error": error}
|
|
)
|
|
|
|
|
|
async def tkmp_exception_handler(request: Request, exc: TKMPException):
|
|
"""TK-MP 커스텀 예외 핸들러"""
|
|
logger.error(f"TK-MP 예외 발생: {exc.message} (코드: {exc.error_code})")
|
|
|
|
return JSONResponse(
|
|
status_code=exc.status_code,
|
|
content=ErrorResponse.create_error_response(
|
|
message=exc.message,
|
|
error_code=exc.error_code,
|
|
status_code=exc.status_code
|
|
)
|
|
)
|
|
|
|
|
|
async def validation_exception_handler(request: Request, exc: RequestValidationError):
|
|
"""검증 예외 핸들러"""
|
|
logger.warning(f"검증 오류: {exc.errors()}")
|
|
|
|
return JSONResponse(
|
|
status_code=422,
|
|
content=ErrorResponse.validation_error_response(exc.errors())
|
|
)
|
|
|
|
|
|
async def sqlalchemy_exception_handler(request: Request, exc: SQLAlchemyError):
|
|
"""SQLAlchemy 예외 핸들러"""
|
|
logger.error(f"데이터베이스 오류: {str(exc)}", exc_info=True)
|
|
|
|
return JSONResponse(
|
|
status_code=500,
|
|
content=ErrorResponse.database_error_response(str(exc))
|
|
)
|
|
|
|
|
|
async def general_exception_handler(request: Request, exc: Exception):
|
|
"""일반 예외 핸들러"""
|
|
logger.error(f"예상치 못한 오류: {str(exc)}", exc_info=True)
|
|
|
|
return JSONResponse(
|
|
status_code=500,
|
|
content=ErrorResponse.create_error_response(
|
|
message="서버 내부 오류가 발생했습니다.",
|
|
error_code="INTERNAL_SERVER_ERROR",
|
|
status_code=500,
|
|
details={"error": str(exc)} if logger.level <= 10 else None # DEBUG 레벨일 때만 상세 에러 표시
|
|
)
|
|
)
|
|
|
|
|
|
def setup_error_handlers(app):
|
|
"""FastAPI 앱에 에러 핸들러 등록"""
|
|
app.add_exception_handler(TKMPException, tkmp_exception_handler)
|
|
app.add_exception_handler(RequestValidationError, validation_exception_handler)
|
|
app.add_exception_handler(SQLAlchemyError, sqlalchemy_exception_handler)
|
|
app.add_exception_handler(Exception, general_exception_handler)
|
|
|
|
logger.info("에러 핸들러 등록 완료")
|