"""失败详情构造函数(D16)。 抽离 ``ChannelControlService._toFailureDetail`` 与 ``AdminMessageService`` 的重复逻辑为模块级函数,供两个 service 复用。 """ from __future__ import annotations from yuxi.channels.contract.dtos.common import FailureDetail from yuxi.channels.contract.errors import Error __all__ = ["toFailureDetail"] def toFailureDetail(target: str, err: Error | None) -> FailureDetail: """将管道错误转换为失败详情。 当 ``err`` 非空时,使用错误的 ``error_code`` 与 ``message`` 构造失败 详情,并提取 ``err.details`` 业务字段存入 ``details``,供 ``raiseOnControlFailure`` 反向重构异常时保留 ``resource`` / ``id`` / ``field`` / ``rule`` 等业务字段;为空时(管道返回失败但未携带错误 对象)使用 ``INTERNAL`` 通用错误码与兜底消息构造。 参数: target: 失败目标(操作类型 / 投递目标等),写入 ``FailureDetail.target``。 err: 管道返回的错误对象,None 时使用通用错误码。 返回: 失败详情。 """ if err is not None: return FailureDetail( target=target, error_code=err.error_code, message=err.message, retryable=False, details=err.details or None, ) return FailureDetail( target=target, error_code="INTERNAL", message="pipeline failed without error", retryable=False, )