feat: SWG 가스켓 전체 구성 정보 표시 개선
Some checks failed
SonarQube Analysis / SonarQube Scan (push) Has been cancelled
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로 완전한 구성 표시 - 외부링/필러/내부링/추가구성 모든 정보 포함 - 구매수량 계산 모달에서 정확한 재질 정보 확인 가능
This commit is contained in:
139
backend/app/utils/error_handlers.py
Normal file
139
backend/app/utils/error_handlers.py
Normal file
@@ -0,0 +1,139 @@
|
||||
"""
|
||||
에러 처리 유틸리티
|
||||
표준화된 에러 응답 및 예외 처리
|
||||
"""
|
||||
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("에러 핸들러 등록 완료")
|
||||
Reference in New Issue
Block a user