datai/docs/archive/decisions/adr/0032-error-handling-exception-mechanism.md

316 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 架构决策记录:错误处理和异常机制完善
## 背景
REQ-011-6 需求要求在 datai-salesforce-integration 模块实现完善的错误处理机制,包括自定义异常类、全局异常处理器、错误日志记录和错误信息封装。通过统一的错误处理机制,提高系统的健壮性,提供清晰的错误信息,提升用户体验。
### 面临的问题
1. **异常类设计**: 需要设计合理的自定义异常类,支持文件上传下载相关的异常场景
2. **错误代码管理**: 需要设计统一的错误代码枚举,集中管理所有错误代码
3. **全局异常处理**: 需要设计全局异常处理器,统一处理所有异常
4. **错误响应封装**: 需要设计统一的错误响应格式,提高 API 接口的一致性
5. **错误日志记录**: 需要设计合理的错误日志记录机制,记录所有错误信息
6. **错误信息国际化**: 需要设计错误信息国际化机制,支持多语言
### 约束条件
1. **技术栈限制**: 必须基于现有的 Spring Boot 3 技术栈
2. **架构约束**: 必须遵循 Authentication.canvas 中定义的架构和调用关系
3. **模块约束**: 必须在 datai-salesforce-integration 模块下实现
4. **文档约束**: 必须遵循 SSOT 方法论
5. **代码规范**: 必须遵循项目编码规范
## 决策
### 1. 自定义异常类设计
**决策**: 定义文件上传下载相关的自定义异常类,所有异常类继承自 RuntimeException
**理由**:
- RuntimeException 是 Java 标准的非受检异常,符合 Spring Boot 异常处理最佳实践
- 继承自 RuntimeException 可以避免强制异常处理,提高代码可读性
- 提供异常链支持cause便于异常追踪
- 提供错误代码和错误消息,便于错误处理和日志记录
**实现方案**:
- 定义 FileUploadException 异常类,包含 errorCode 字段
- 定义 FileDownloadException 异常类,包含 errorCode 字段
- 定义 FileSizeExceededException 异常类,包含 actualSize 和 maxSize 字段
- 定义 FileTypeNotSupportedException 异常类,包含 actualType 和 supportedTypes 字段
- 定义 FileObjectNotFoundException 异常类,包含 objectId 和 objectType 字段
- 定义 OrgConfigNotFoundException 异常类,包含 orgConfigId 字段
- 定义 FileValidationException 异常类,包含 validationType 字段
- 所有异常类继承自 RuntimeException
- 使用 Lombok 注解(@Data、@AllArgsConstructor、@NoArgsConstructor简化代码
### 2. 错误代码枚举设计
**决策**: 定义 FileErrorCode 枚举,统一管理所有错误代码
**理由**:
- 使用枚举可以集中管理错误代码,避免魔法值
- 提供错误代码的描述信息,便于错误处理和日志记录
- 提供 HTTP 状态码,便于返回正确的 HTTP 状态码
- 提供静态方法进行转换,提高代码可读性
**实现方案**:
- 定义 FileErrorCode 枚举,包含所有文件上传下载相关的错误代码
- 每个枚举值包含 code、description、httpStatus 字段
- 提供 getByCode() 静态方法,根据错误代码获取枚举值
- 提供 getByHttpStatus() 静态方法,根据 HTTP 状态码获取枚举值
- 使用 @Getter 注解简化代码
### 3. 全局异常处理器设计
**决策**: 实现 FileGlobalExceptionHandler 类,使用 @RestControllerAdvice 注解
**理由**:
- @RestControllerAdvice 是 Spring Boot 3 推荐的全局异常处理器注解
- 可以统一处理所有异常,避免重复的异常处理代码
- 可以返回统一的错误响应格式,提高 API 接口的一致性
- 可以记录错误日志,便于问题排查
**实现方案**:
- 定义 FileGlobalExceptionHandler 类,使用 @RestControllerAdvice 注解
- 使用 @Slf4j 注解记录日志
- 使用 @ExceptionHandler 注解处理各种异常:
- 处理 FileUploadException 异常
- 处理 FileDownloadException 异常
- 处理 FileSizeExceededException 异常
- 处理 FileTypeNotSupportedException 异常
- 处理 FileObjectNotFoundException 异常
- 处理 OrgConfigNotFoundException 异常
- 处理 FileValidationException 异常
- 处理 MethodArgumentNotValidException 异常(参数验证失败)
- 处理 HttpRequestMethodNotSupportedException 异常HTTP 方法不支持)
- 处理 HttpMediaTypeNotSupportedException 异常Content-Type 不支持)
- 处理 MaxUploadSizeExceededException 异常(文件大小超限)
- 处理其他未捕获的异常
- 返回统一的错误响应格式ErrorResponse
- 记录详细的错误日志
### 4. 错误响应封装设计
**决策**: 定义 ErrorResponse 响应类,封装错误信息
**理由**:
- 统一的错误响应格式可以提高 API 接口的一致性
- 便于前端处理错误响应
- 便于错误处理和日志记录
- 符合业界最佳实践
**实现方案**:
- 定义 ErrorResponse 响应类,包含以下字段:
- code错误代码
- message错误消息
- details错误详情可选
- timestamp时间戳
- path请求路径可选
- 使用 Lombok 注解(@Data、@Builder、@AllArgsConstructor、@NoArgsConstructor简化代码
- 提供静态工厂方法,便于构建错误响应
### 5. 错误日志记录设计
**决策**: 在全局异常处理器中记录错误日志,使用 Slf4j
**理由**:
- Slf4j 是 Java 标准的日志框架,符合 Spring Boot 最佳实践
- 可以记录详细的错误信息,便于问题排查
- 可以使用不同的日志级别,区分错误严重程度
- 可以配置日志格式和输出位置
**实现方案**:
- 在全局异常处理器中使用 @Slf4j 记录日志
- 记录异常类型
- 记录错误信息
- 记录错误代码
- 记录请求参数
- 记录请求路径
- 记录时间戳
- 记录异常堆栈(可选)
- 使用不同的日志级别:
- ERROR记录业务异常
- WARN记录参数验证异常
- ERROR记录未捕获的异常
### 6. 错误信息国际化设计
**决策**: 实现错误信息国际化,使用 Spring 的 MessageSource
**理由**:
- 支持多语言可以提高用户体验
- Spring 的 MessageSource 是标准的国际化解决方案
- 可以根据请求头 Accept-Language 返回对应语言的错误信息
- 符合业界最佳实践
**实现方案**:
- 定义错误信息资源文件:
- messages.properties默认英文
- messages_zh_CN.properties中文
- 在资源文件中定义所有错误信息
- 在全局异常处理器中使用 MessageSource 获取错误信息
- 根据请求头 Accept-Language 返回对应语言的错误信息
- 使用 LocaleContextHolder 获取当前 Locale
## 备选方案
### 方案 1: 使用受检异常
**优点**:
- 强制调用者处理异常,提高代码健壮性
- 编译时检查,避免遗漏异常处理
**缺点**:
- 增加代码复杂度,需要大量 try-catch 块
- 不符合 Spring Boot 异常处理最佳实践
- 降低代码可读性
**评估**: 不推荐使用
### 方案 2: 不使用全局异常处理器
**优点**:
- 灵活性高,每个方法可以自定义异常处理
**缺点**:
- 代码冗余,重复的异常处理代码
- 错误响应格式不统一
- 不便于错误日志记录
**评估**: 不推荐使用
### 方案 3: 不实现国际化
**优点**:
- 实现简单,减少开发成本
**缺点**:
- 不支持多语言,用户体验差
- 不符合国际化最佳实践
**评估**: 不推荐使用
## 影响
### 系统架构影响
1. **新增模块**: 在 datai-salesforce-integration 模块下新增异常处理相关类
2. **新增异常类**: 新增 7 个自定义异常类
3. **新增枚举类**: 新增 FileErrorCode 枚举类
4. **新增处理器**: 新增 FileGlobalExceptionHandler 全局异常处理器
5. **新增响应类**: 新增 ErrorResponse 错误响应类
6. **新增资源文件**: 新增错误信息资源文件
### 开发流程影响
1. **开发流程**: 需要按照 SSOT 方法论进行开发,包括需求定义、方案决策、提示词资产化、执行会话、变更记录、闭环复盘
2. **代码规范**: 需要遵循项目编码规范,使用 Lombok 注解、Slf4j、Spring Boot 注解等
3. **测试要求**: 需要编写单元测试和集成测试,确保测试覆盖率 ≥ 90%
### 运维管理影响
1. **监控要求**: 需要监控错误日志,及时发现和解决问题
2. **日志要求**: 需要记录详细的错误日志,便于问题排查
3. **国际化要求**: 需要维护错误信息资源文件,确保多语言支持
## 风险
### 技术风险
1. **异常类设计风险**: 异常类设计可能不够完善
- **缓解措施**: 提前进行异常类设计评审,参考业界最佳实践
2. **错误代码管理风险**: 错误代码可能不够统一
- **缓解措施**: 使用枚举集中管理错误代码,提供静态方法进行转换
3. **全局异常处理器风险**: 全局异常处理器可能影响其他模块
- **缓解措施**: 使用 @RestControllerAdvice 注解,只处理文件上传下载相关的异常
4. **错误日志记录风险**: 错误日志记录可能不够详细
- **缓解措施**: 记录详细的错误信息,包括异常类型、错误信息、错误代码、请求参数、请求路径、时间戳等
### 业务风险
1. **兼容性风险**: 前端可能不兼容新的错误响应格式
- **缓解措施**: 提供详细的 API 文档,提供前端集成指南
2. **国际化风险**: 国际化实现可能不够完善
- **缓解措施**: 提前进行国际化测试,确保多语言支持
### 实施风险
1. **开发风险**: 开发过程中可能遇到技术难题
- **缓解措施**: 提前进行技术调研,参考官方文档和示例代码
2. **测试风险**: 测试过程中可能发现性能问题
- **缓解措施**: 提前进行性能测试,优化代码性能
## 回滚策略
### 回滚条件
1. **功能不满足需求**: 如果实现的功能不满足需求,可以进行回滚
2. **性能不达标**: 如果性能不达标,可以进行回滚或优化
3. **严重Bug**: 如果发现严重Bug可以进行回滚或修复
### 回滚步骤
1. **代码回滚**: 使用 Git 回滚代码到上一个稳定版本
2. **配置回滚**: 如果有配置变更,需要回滚配置
3. **通知用户**: 通知用户回滚的原因和影响
### 回滚后调整
1. **问题分析**: 分析回滚的原因,找出问题所在
2. **方案优化**: 优化方案,解决存在的问题
3. **重新实施**: 重新实施优化后的方案
## 验收标准
### 功能验收标准
1. **异常处理**: 能够正确处理所有异常,提供清晰的错误信息
2. **错误响应**: 能够返回统一的错误响应格式
3. **错误日志**: 能够记录详细的错误日志,便于问题排查
4. **国际化**: 能够根据请求头返回对应语言的错误信息
5. **参数验证**: 能够正确处理参数验证异常,提供详细的错误信息
### 性能验收标准
1. **异常处理性能**: 异常处理性能良好,不影响系统响应
2. **日志记录性能**: 日志记录性能良好,不影响系统响应
### 代码质量验收标准
1. **代码规范**: 代码符合项目编码规范,有清晰的注释
2. **单一职责**: 遵循单一职责原则和开闭原则
3. **测试覆盖**: 测试覆盖率 ≥ 90%
### 国际化验收标准
1. **多语言支持**: 支持中文和英文
2. **语言切换**: 能够根据请求头正确切换语言
3. **错误信息**: 错误信息准确、清晰
## 视觉锚点
### Visual Reference
引用 Canvas 的具体节点或快照:
- [Authentication.canvas](../../Authentication.canvas) - 项目架构视觉化展示
- **具体节点**: [通用异常](node_common_exception) - 定义Salesforce相关的异常类
- **具体节点**: [集成核心](node_integration_core) - 提供与Salesforce的各种连接方式
### Status
- [x] Draft
- [ ] Accepted
- [ ] Superceded
## 参考资料
列出与该决策相关的参考资料,包括文档、文章或其他资源。
- [REQ-011.md](../requirements/REQ-011.md) - Salesforce文件上传下载功能
- [REQ-011-1.md](../requirements/REQ-011-1.md) - 基础设施和枚举定义
- [REQ-011-6.md](../requirements/REQ-011-6.md) - 错误处理和异常机制完善
- [0027-file-infrastructure-enums.md](0027-file-infrastructure-enums.md) - 文件上传下载基础设施架构决策
- [Spring Boot 异常处理文档](https://spring.io/guides/gs/exception-handling/) - Spring Boot 异常处理官方文档
- [Spring Boot 国际化文档](https://spring.io/guides/gs/handling-form-submission/) - Spring Boot 国际化官方文档