You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python如何实现以其他枚举为键的ErrorMap错误映射枚举

实现方案

按照单一职责原则拆分各模块实现,可完全匹配预期调用模式,且支持多领域错误枚举扩展:

1. 基础依赖与异常基类

首先定义公共依赖、所有领域异常的基类,以及具体业务异常:

from enum import Enum
from typing import Generic, TypeVar, Optional, Type
from pydantic import BaseModel

Dto = TypeVar("Dto", bound=BaseModel)

# 所有自定义领域异常的公共基类,方便上层统一捕获
class BaseDomainException(Exception):
    def __init__(self, message: str, **kwargs):
        self.message = message
        super().__init__(message)

# 示例具体异常实现
class GenericErrorException(BaseDomainException):
    pass
class CartNotFoundException(BaseDomainException):
    pass
class OutOfStockException(BaseDomainException):
    pass

2. 领域错误枚举定义

枚举类仅负责定义错误slug标识,不掺杂任何映射逻辑:

class DomainErrorEnum(Enum):
    GENERIC_ERROR = "GENERIC_ERROR"
    NOT_FOUND = "NOT_FOUND"
    OUT_OF_STOCK = "OUT_OF_STOCK"

3. ErrorMap映射实现

不要强行继承Enum(多枚举场景下Enum多继承存在语法限制,且无法匹配预期的索引调用写法),通过重写类级索引方法实现完全一致的调用体验,同时支持后续扩展注册多业务域的错误映射:

class ErrorMap:
    _MAPPING: dict[Enum, Type[BaseDomainException]] = {
        DomainErrorEnum.GENERIC_ERROR: GenericErrorException,
        DomainErrorEnum.NOT_FOUND: CartNotFoundException,
        DomainErrorEnum.OUT_OF_STOCK: OutOfStockException
    }

    def __class_getitem__(cls, error_code: Enum) -> Type[BaseDomainException]:
        # 未配置映射的错误统一返回通用异常
        return cls._MAPPING.get(error_code, GenericErrorException)
    
    @classmethod
    def register(cls, error_code: Enum, exception_cls: Type[BaseDomainException]):
        """扩展方法:注册其他业务域的错误-异常映射"""
        cls._MAPPING[error_code] = exception_cls

4. 修正Result与BaseError模型

修复原定义中的字段声明错误,补充成功状态判断、异常实例化逻辑:

class BaseError(BaseModel):
    error_code: DomainErrorEnum
    message: str

    def raise_error(self):
        # 实例化对应异常,传入错误上下文信息
        raise ErrorMap[self.error_code](self.message)


class Result(BaseModel, Generic[Dto]):
    error: Optional[BaseError] = None
    data: Optional[Dto] = None

    @property
    def is_success(self) -> bool:
        return self.error is None

调用示例

完全兼容给出的业务场景写法:

# 领域层用例
def specific_use_case():
    # 适配器层返回Result结构,不直接抛异常
    result_search: Result[ProductDto] = adapter.search_product()
    if result_search.is_success:
        data: ProductDto = result_search.data
        # 纯业务逻辑层可直接抛异常,不依赖Result包装
        business_rules_method(data)
        return entity
    
    # 自动抛出对应类型的领域异常
    result_search.error.raise_error()

后续新增其他业务域的错误枚举时,只需要定义对应枚举和异常类,调用ErrorMap.register()注册映射即可,不需要修改核心逻辑。


内容的提问来源于stack exchange,提问作者Tâmer Cuba

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 23:18:19