refactor(error): 规范化分层错误类型并优化异常捕捉

- 新增 tracing 记录异常,移除不必要的 Result
- 重构 错误处理架构
This commit is contained in:
2026-07-20 20:18:38 +08:00
parent 913ff4d884
commit 3499e89bf1
11 changed files with 140 additions and 101 deletions

View File

@@ -73,7 +73,8 @@ use thiserror::Error;
// }
/// 统一用我们自己的 DdddError 包装 Result
pub type Result<T> = std::result::Result<T, DdddError>;
// pub type Result<T> = std::result::Result<T, DdddError>;
pub type Result<T, E = DdddError> = std::result::Result<T, E>;
// =====================================================================
// 1. 顶层全局 Error 分流器 (去 anyhow 化,完全基于标准库/自定义类型)
// =====================================================================
@@ -83,27 +84,26 @@ pub enum DdddError {
// /// 系统文件、网络等原生 I/O 异常 (高优先级自动转换)
// #[error("系统网络或文件 I/O 异常: {0}")]
// Io(#[from] std::io::Error),
/// 图像预处理阶段发生异常
#[error("图像预处理失败: {0}")]
Preprocess(#[from] ImagePreprocessReason),
Preprocess(#[from] ImagePreprocessError),
/// 推理引擎与张量操作阶段发生异常
#[error("推理与模型输入/输出张量异常: {0}")]
Inference(#[from] TensorErrorReason),
Inference(#[from] TensorError),
/// 算法后处理解码阶段发生异常
#[error("后处理解码错误: {0}")]
Decode(#[from] DecodeReason),
Decode(#[from] DecodeError),
/// 框架内部不可恢复的逻辑断言错误(例如解析节点 Fact 失败)
#[error("内部严重逻辑错误: {0}")]
Internal(String),
/// 【流派核心】接替 anyhow::Error 的用户自定义扩展错误
/// 【流派核心】接替 anyhow::Error 的用户自定义扩展错误
/// 承载任何第三方扩展、解密、特定预处理插件在执行时产生的自定义错误
#[error("用户自定义扩展错误: {0}")]
Other(Box<dyn std::error::Error + Send + Sync>),
Other(#[source]Box<dyn std::error::Error + Send + Sync>),
}
// =====================================================================
@@ -111,7 +111,7 @@ pub enum DdddError {
// =====================================================================
#[derive(Error, Debug)]
pub enum ImagePreprocessReason {
pub enum ImagePreprocessError {
// #[error("图片加载或解码失败: {0}")]
// ImageIo(#[from] image::ImageError),
// image_io
@@ -119,14 +119,16 @@ pub enum ImagePreprocessReason {
Ndarray(#[from] ndarray::ShapeError),
// image_io
#[error("图像矩阵维度不合规!预期: {expected},实际图像形状: {actual:?}")]
InvalidImageDimensions {
InvalidDimensions {
expected: String,
actual: Vec<usize>,
},
// image_io
/// 从 ndarray 原始数据构建图像缓冲区时,缓冲区长度与分辨率/通道数不匹配
#[error("图像缓冲区长度不匹配!预期大小: {expected},实际大小: {actual} (分辨率: {width}x{height}, 通道数: {channels})")]
#[error(
"图像缓冲区长度不匹配!预期大小: {expected},实际大小: {actual} (分辨率: {width}x{height}, 通道数: {channels})"
)]
BufferLengthMismatch {
expected: usize,
actual: usize,
@@ -137,7 +139,18 @@ pub enum ImagePreprocessReason {
// image_io
#[error("不支持的图像通道数: {0} (仅支持单通道灰度L、3通道RGB、4通道RGBA)")]
UnsupportedChannels(usize),
// ================= 新增:针对 HSV 和 Preset 的强类型错误 =================
/// HSV 颜色区间非法 (例如 H > 180 或 lower > upper)
#[error("HSV 颜色区间参数非法: {0}")]
InvalidHsvRange (String ),
/// 不支持或未知的颜色预设名称
#[error("不支持的颜色预设名称: {0}")]
UnknownColorPreset(String),
/// 颜色过滤器/预处理规则配置非法导致失败
#[error("颜色过滤器配置无效或初始化失败: {0}")]
FilterConfigInvalid(String),
// #[error("Base64 解码失败: {0}")]
// Base64(#[from] base64::DecodeError),
//
@@ -153,14 +166,14 @@ pub enum ImagePreprocessReason {
// =====================================================================
#[derive(Error, Debug)]
pub enum TensorErrorReason {
pub enum TensorError {
/// 替换原有的 anyhow::Error明确将 Tract/ONNX 引擎底层报错序列化为干净的 String
#[error("推理引擎内部发生异常: {0}")]
EngineError(String),
Engine(String),
/// 模型张量维度不匹配 (原有的顶层 DimensionMismatch 被优雅地归入本模块)
#[error("模型张量维度不匹配!预期: {expected},实际 Tensor 形状: {actual:?}")]
TensorDimensionMismatch {
DimensionMismatch {
expected: String,
actual: Vec<usize>,
},
@@ -169,7 +182,7 @@ pub enum TensorErrorReason {
/// 直接包装 ndarray::ShapeError保留强类型完美支持 match
#[error("OCR Logits 矩阵变形失败: {0}")]
LogitsDimensionMismatch(#[from] ndarray::ShapeError),
/// 张量内存布局不是连续的
#[error("内存不连续,无法执行零拷贝操作")]
NonContiguousMemory,
@@ -184,10 +197,10 @@ pub enum TensorErrorReason {
// =====================================================================
#[derive(Error, Debug)]
pub enum DecodeReason {
pub enum DecodeError {
/// CTC 解码器解码过程中的逻辑报错
#[error("CTC 解码异常: {0}")]
CtcDecodeError(String),
Ctc(String),
}
// =====================================================================
@@ -223,7 +236,7 @@ impl DdddError {
pub fn is_invalid_dimensions(&self) -> bool {
matches!(
self,
DdddError::Preprocess(ImagePreprocessReason::InvalidImageDimensions { .. })
DdddError::Preprocess(ImagePreprocessError::InvalidDimensions { .. })
)
}
@@ -231,22 +244,21 @@ impl DdddError {
pub fn is_unsupported_channels(&self) -> bool {
matches!(
self,
DdddError::Preprocess(ImagePreprocessReason::UnsupportedChannels(_))
DdddError::Preprocess(ImagePreprocessError::UnsupportedChannels(_))
)
}
/// 提取出底层最原始的那个错误(无论是 IO、预处理、推理、还是第三方扩展错误
/// 方便外层统一打印更深层的 `source` 链条
pub fn source_error(&self) -> Option<&(dyn std::error::Error + 'static)> {
use std::error::Error;
match self {
// DdddError::Io(err) => Some(err),
DdddError::Preprocess(err) => Some(err),
DdddError::Inference(err) => Some(err),
DdddError::Decode(err) => Some(err),
DdddError::Other(err) => Some(err.as_ref()),
DdddError::Internal(_) => None, // Internal 内部目前只有 String没有底层的 Error source
}
}
// 提取出底层最原始的那个错误(无论是 IO、预处理、推理、还是第三方扩展错误
// 方便外层统一打印更深层的 `source` 链条
// pub fn source_error(&self) -> Option<&(dyn std::error::Error + 'static)> {
// use std::error::Error;
// match self {
// // DdddError::Io(err) => Some(err),
// DdddError::Preprocess(err) => Some(err),
// DdddError::Inference(err) => Some(err),
// DdddError::Decode(err) => Some(err),
// DdddError::Other(err) => Some(err.as_ref()),
// DdddError::Internal(_) => None, // Internal 内部目前只有 String没有底层的 Error source
// }
// }
}