362 lines
11 KiB
Python
362 lines
11 KiB
Python
# -*- coding: utf-8 -*-
|
|
"""
|
|
커스텀 예외 모듈
|
|
애플리케이션에서 사용되는 커스텀 예외 클래스들을 정의합니다.
|
|
|
|
각 예외는 특정 오류 상황을 명확하게 나타내며,
|
|
적절한 오류 처리를 가능하게 합니다.
|
|
"""
|
|
|
|
|
|
class HandoverBaseException(Exception):
|
|
"""
|
|
애플리케이션 기본 예외 클래스
|
|
|
|
모든 커스텀 예외의 기반 클래스입니다.
|
|
"""
|
|
|
|
def __init__(self, message: str = "알 수 없는 오류가 발생했습니다."):
|
|
self.message = message
|
|
super().__init__(self.message)
|
|
|
|
def __str__(self):
|
|
return f"[{self.__class__.__name__}] {self.message}"
|
|
|
|
|
|
# ============================================================================
|
|
# 데이터베이스 관련 예외
|
|
# ============================================================================
|
|
|
|
class DatabaseException(HandoverBaseException):
|
|
"""데이터베이스 관련 기본 예외"""
|
|
pass
|
|
|
|
|
|
class DatabaseConnectionError(DatabaseException):
|
|
"""데이터베이스 연결 실패 예외"""
|
|
|
|
def __init__(self, message: str = "데이터베이스 연결에 실패했습니다."):
|
|
super().__init__(message)
|
|
|
|
|
|
class DatabaseQueryError(DatabaseException):
|
|
"""데이터베이스 쿼리 실행 실패 예외"""
|
|
|
|
def __init__(self, message: str = "데이터베이스 쿼리 실행에 실패했습니다.", query: str = None):
|
|
self.query = query
|
|
if query:
|
|
message = f"{message} (Query: {query[:100]}...)"
|
|
super().__init__(message)
|
|
|
|
|
|
class RecordNotFoundError(DatabaseException):
|
|
"""레코드를 찾을 수 없는 예외"""
|
|
|
|
def __init__(self, table: str = None, record_id: int = None):
|
|
message = "레코드를 찾을 수 없습니다."
|
|
if table and record_id:
|
|
message = f"테이블 '{table}'에서 ID {record_id}인 레코드를 찾을 수 없습니다."
|
|
super().__init__(message)
|
|
|
|
|
|
class DuplicateRecordError(DatabaseException):
|
|
"""중복 레코드 예외"""
|
|
|
|
def __init__(self, message: str = "중복된 레코드가 존재합니다."):
|
|
super().__init__(message)
|
|
|
|
|
|
# ============================================================================
|
|
# 인증/권한 관련 예외
|
|
# ============================================================================
|
|
|
|
class AuthException(HandoverBaseException):
|
|
"""인증 관련 기본 예외"""
|
|
pass
|
|
|
|
|
|
class AuthenticationError(AuthException):
|
|
"""인증 실패 예외"""
|
|
|
|
def __init__(self, message: str = "인증에 실패했습니다."):
|
|
super().__init__(message)
|
|
|
|
|
|
class InvalidCredentialsError(AuthException):
|
|
"""잘못된 자격 증명 예외"""
|
|
|
|
def __init__(self, message: str = "아이디 또는 비밀번호가 올바르지 않습니다."):
|
|
super().__init__(message)
|
|
|
|
|
|
class PermissionDeniedError(AuthException):
|
|
"""권한 없음 예외"""
|
|
|
|
def __init__(self, action: str = None):
|
|
message = "이 작업을 수행할 권한이 없습니다."
|
|
if action:
|
|
message = f"'{action}' 작업을 수행할 권한이 없습니다."
|
|
super().__init__(message)
|
|
|
|
|
|
class SessionExpiredError(AuthException):
|
|
"""세션 만료 예외"""
|
|
|
|
def __init__(self, message: str = "세션이 만료되었습니다. 다시 로그인해주세요."):
|
|
super().__init__(message)
|
|
|
|
|
|
class UserNotActiveError(AuthException):
|
|
"""비활성 사용자 예외"""
|
|
|
|
def __init__(self, message: str = "비활성화된 계정입니다. 관리자에게 문의하세요."):
|
|
super().__init__(message)
|
|
|
|
|
|
# ============================================================================
|
|
# 설정 관련 예외
|
|
# ============================================================================
|
|
|
|
class ConfigException(HandoverBaseException):
|
|
"""설정 관련 기본 예외"""
|
|
pass
|
|
|
|
|
|
class ConfigFileNotFoundError(ConfigException):
|
|
"""설정 파일을 찾을 수 없는 예외"""
|
|
|
|
def __init__(self, filepath: str = None):
|
|
message = "설정 파일을 찾을 수 없습니다."
|
|
if filepath:
|
|
message = f"설정 파일을 찾을 수 없습니다: {filepath}"
|
|
super().__init__(message)
|
|
|
|
|
|
class ConfigParseError(ConfigException):
|
|
"""설정 파일 파싱 오류 예외"""
|
|
|
|
def __init__(self, message: str = "설정 파일 파싱에 실패했습니다."):
|
|
super().__init__(message)
|
|
|
|
|
|
class InvalidConfigValueError(ConfigException):
|
|
"""잘못된 설정 값 예외"""
|
|
|
|
def __init__(self, key: str = None, value: str = None):
|
|
message = "잘못된 설정 값입니다."
|
|
if key:
|
|
message = f"잘못된 설정 값입니다: {key}={value}"
|
|
super().__init__(message)
|
|
|
|
|
|
# ============================================================================
|
|
# 유효성 검사 관련 예외
|
|
# ============================================================================
|
|
|
|
class ValidationException(HandoverBaseException):
|
|
"""유효성 검사 관련 기본 예외"""
|
|
pass
|
|
|
|
|
|
class InvalidInputError(ValidationException):
|
|
"""잘못된 입력 예외"""
|
|
|
|
def __init__(self, field: str = None, message: str = None):
|
|
if message:
|
|
error_message = message
|
|
elif field:
|
|
error_message = f"'{field}' 필드의 입력값이 올바르지 않습니다."
|
|
else:
|
|
error_message = "입력값이 올바르지 않습니다."
|
|
super().__init__(error_message)
|
|
|
|
|
|
class RequiredFieldError(ValidationException):
|
|
"""필수 필드 누락 예외"""
|
|
|
|
def __init__(self, field: str = None):
|
|
message = "필수 필드가 누락되었습니다."
|
|
if field:
|
|
message = f"필수 필드 '{field}'이(가) 누락되었습니다."
|
|
super().__init__(message)
|
|
|
|
|
|
class InvalidDateFormatError(ValidationException):
|
|
"""잘못된 날짜 형식 예외"""
|
|
|
|
def __init__(self, value: str = None, expected_format: str = "YYYY-MM-DD"):
|
|
message = f"잘못된 날짜 형식입니다. 예상 형식: {expected_format}"
|
|
if value:
|
|
message = f"'{value}'은(는) 올바른 날짜 형식이 아닙니다. 예상 형식: {expected_format}"
|
|
super().__init__(message)
|
|
|
|
|
|
class InvalidTimeFormatError(ValidationException):
|
|
"""잘못된 시간 형식 예외"""
|
|
|
|
def __init__(self, value: str = None, expected_format: str = "HH:MM"):
|
|
message = f"잘못된 시간 형식입니다. 예상 형식: {expected_format}"
|
|
if value:
|
|
message = f"'{value}'은(는) 올바른 시간 형식이 아닙니다. 예상 형식: {expected_format}"
|
|
super().__init__(message)
|
|
|
|
|
|
# ============================================================================
|
|
# 네트워크 관련 예외
|
|
# ============================================================================
|
|
|
|
class NetworkException(HandoverBaseException):
|
|
"""네트워크 관련 기본 예외"""
|
|
pass
|
|
|
|
|
|
class NetworkConnectionError(NetworkException):
|
|
"""네트워크 연결 실패 예외"""
|
|
|
|
def __init__(self, message: str = "네트워크 연결에 실패했습니다."):
|
|
super().__init__(message)
|
|
|
|
|
|
class APIRequestError(NetworkException):
|
|
"""API 요청 실패 예외"""
|
|
|
|
def __init__(self, url: str = None, status_code: int = None):
|
|
message = "API 요청에 실패했습니다."
|
|
if url and status_code:
|
|
message = f"API 요청 실패: {url} (상태 코드: {status_code})"
|
|
super().__init__(message)
|
|
|
|
|
|
class SyncError(NetworkException):
|
|
"""동기화 실패 예외"""
|
|
|
|
def __init__(self, message: str = "데이터 동기화에 실패했습니다."):
|
|
super().__init__(message)
|
|
|
|
|
|
# ============================================================================
|
|
# 업데이트 관련 예외
|
|
# ============================================================================
|
|
|
|
class UpdateException(HandoverBaseException):
|
|
"""업데이트 관련 기본 예외"""
|
|
pass
|
|
|
|
|
|
class UpdateCheckError(UpdateException):
|
|
"""업데이트 확인 실패 예외"""
|
|
|
|
def __init__(self, message: str = "업데이트 확인에 실패했습니다."):
|
|
super().__init__(message)
|
|
|
|
|
|
class UpdateDownloadError(UpdateException):
|
|
"""업데이트 다운로드 실패 예외"""
|
|
|
|
def __init__(self, message: str = "업데이트 다운로드에 실패했습니다."):
|
|
super().__init__(message)
|
|
|
|
|
|
class UpdateInstallError(UpdateException):
|
|
"""업데이트 설치 실패 예외"""
|
|
|
|
def __init__(self, message: str = "업데이트 설치에 실패했습니다."):
|
|
super().__init__(message)
|
|
|
|
|
|
# ============================================================================
|
|
# 파일 관련 예외
|
|
# ============================================================================
|
|
|
|
class FileException(HandoverBaseException):
|
|
"""파일 관련 기본 예외"""
|
|
pass
|
|
|
|
|
|
class FileNotFoundError(FileException):
|
|
"""파일을 찾을 수 없는 예외"""
|
|
|
|
def __init__(self, filepath: str = None):
|
|
message = "파일을 찾을 수 없습니다."
|
|
if filepath:
|
|
message = f"파일을 찾을 수 없습니다: {filepath}"
|
|
super().__init__(message)
|
|
|
|
|
|
class FileReadError(FileException):
|
|
"""파일 읽기 실패 예외"""
|
|
|
|
def __init__(self, filepath: str = None):
|
|
message = "파일 읽기에 실패했습니다."
|
|
if filepath:
|
|
message = f"파일 읽기에 실패했습니다: {filepath}"
|
|
super().__init__(message)
|
|
|
|
|
|
class FileWriteError(FileException):
|
|
"""파일 쓰기 실패 예외"""
|
|
|
|
def __init__(self, filepath: str = None):
|
|
message = "파일 쓰기에 실패했습니다."
|
|
if filepath:
|
|
message = f"파일 쓰기에 실패했습니다: {filepath}"
|
|
super().__init__(message)
|
|
|
|
|
|
# ============================================================================
|
|
# 내보내기
|
|
# ============================================================================
|
|
|
|
__all__ = [
|
|
# 기본 예외
|
|
'HandoverBaseException',
|
|
|
|
# 데이터베이스 예외
|
|
'DatabaseException',
|
|
'DatabaseConnectionError',
|
|
'DatabaseQueryError',
|
|
'RecordNotFoundError',
|
|
'DuplicateRecordError',
|
|
|
|
# 인증/권한 예외
|
|
'AuthException',
|
|
'AuthenticationError',
|
|
'InvalidCredentialsError',
|
|
'PermissionDeniedError',
|
|
'SessionExpiredError',
|
|
'UserNotActiveError',
|
|
|
|
# 설정 예외
|
|
'ConfigException',
|
|
'ConfigFileNotFoundError',
|
|
'ConfigParseError',
|
|
'InvalidConfigValueError',
|
|
|
|
# 유효성 검사 예외
|
|
'ValidationException',
|
|
'InvalidInputError',
|
|
'RequiredFieldError',
|
|
'InvalidDateFormatError',
|
|
'InvalidTimeFormatError',
|
|
|
|
# 네트워크 예외
|
|
'NetworkException',
|
|
'NetworkConnectionError',
|
|
'APIRequestError',
|
|
'SyncError',
|
|
|
|
# 업데이트 예외
|
|
'UpdateException',
|
|
'UpdateCheckError',
|
|
'UpdateDownloadError',
|
|
'UpdateInstallError',
|
|
|
|
# 파일 예외
|
|
'FileException',
|
|
'FileNotFoundError',
|
|
'FileReadError',
|
|
'FileWriteError',
|
|
]
|
|
|
|
|