# API调用错误处理规范 ## 概述 本文档定义了API调用接口的统一错误处理规范,包括错误码定义、响应结构、错误处理流程等。 ## 响应结构 ### 成功响应 ```json { "code": 0, "message": "业务成功", "transaction_id": "api_call_123456", "data": "加密的响应数据" } ``` ### 错误响应 ```json { "code": 1001, "message": "接口异常", "transaction_id": "api_call_123456" } ``` ## 错误码定义 | 错误码 | 错误类型 | 说明 | |--------|----------|------| | 0 | 业务成功 | 调用成功 | | 1000 | 查询为空 | 查询结果为空 | | 1001 | 接口异常 | 系统异常、数据源异常等 | | 1002 | 参数解密失败 | 请求参数解密失败 | | 1003 | 基础参数校验不正确 | 请求参数格式错误 | | 1004 | 未经授权的IP | IP不在白名单内 | | 1005 | 缺少Access-Id | 请求头中缺少Access-Id | | 1006 | 未经授权的AccessId | AccessId无效或账户已冻结 | | 1007 | 账户余额不足,无法请求 | 钱包余额不足 | | 1008 | 未开通此产品 | 产品不存在、已停用或未订阅 | | 2001 | 业务失败 | 第三方API业务逻辑失败 | ## 实现架构 ### 1. 错误类型定义 - 位置:`internal/application/api/errors.go` - 功能:定义具体的错误类型常量和错误码映射 ### 2. 响应结构定义 - 位置:`internal/application/api/dto/api_response.go` - 功能:定义统一的响应结构体和工厂方法 ### 3. 应用层错误处理 - 位置:`internal/application/api/api_application_service.go` - 功能:在业务逻辑中返回具体的错误类型 ### 4. Handler层统一处理 - 位置:`internal/infrastructure/http/handlers/api_handler.go` - 功能:根据错误类型返回对应的错误码和响应 ## 错误处理流程 ### 1. 基础参数校验(Handler层) ```go // 检查Access-Id accessId := c.GetHeader("Access-Id") if accessId == "" { response := dto.NewErrorResponse(1005, "缺少Access-Id", "") c.JSON(400, response) return } // 参数绑定和校验 if err := h.validator.BindAndValidate(c, &cmd); err != nil { response := dto.NewErrorResponse(1003, "基础参数校验不正确", "") c.JSON(400, response) return } ``` ### 2. 业务逻辑错误处理(应用层) ```go // 用户不存在 if err != nil { return ErrInvalidAccessId } // 账户已冻结 if apiUser.IsFrozen() { return ErrFrozenAccount } // IP不在白名单 if !apiUser.IsWhiteListed(cmd.ClientIP) { return ErrInvalidIP } ``` ### 3. 统一错误响应(Handler层) ```go // 调用应用服务 transactionId, encryptedResp, err := h.appService.CallApi(c.Request.Context(), &cmd) if err != nil { // 根据错误类型返回对应的错误码 errorCode := api.GetErrorCode(err) response := dto.NewErrorResponse(errorCode, err.Error(), transactionId) c.JSON(200, response) // API调用接口统一返回200状态码 return } ``` ## 中间件简化 原来的API认证中间件已经简化,只保留IP获取功能: - 认证逻辑移到Handler层处理 - 保持中间件职责单一 - 便于错误码的统一管理 ## 测试 错误处理逻辑包含完整的单元测试: ```bash go test ./internal/application/api -v ``` ## 使用示例 ### 成功调用 ```bash curl -X POST "http://localhost:8080/api/v1/test_api" \ -H "Access-Id: your_access_id" \ -H "Content-Type: application/json" \ -d '{"data": "encrypted_request_data"}' ``` 响应: ```json { "code": 0, "message": "业务成功", "transaction_id": "api_call_123456", "data": "encrypted_response_data" } ``` ### 错误调用示例 ```bash # 缺少Access-Id curl -X POST "http://localhost:8080/api/v1/test_api" \ -H "Content-Type: application/json" \ -d '{"data": "encrypted_request_data"}' ``` 响应: ```json { "code": 1005, "message": "缺少Access-Id", "transaction_id": "" } ``` ## 扩展说明 1. **新增错误类型**:在`errors.go`中添加新的错误常量和错误码映射 2. **错误码调整**:修改`ErrorCodeMap`中的映射关系 3. **响应结构扩展**:在`api_response.go`中添加新的响应字段或方法 4. **国际化支持**:可以在错误消息中添加多语言支持 ## 注意事项 1. API调用接口统一返回HTTP 200状态码,错误通过响应体中的code字段区分 2. 所有错误响应都包含transaction_id,便于问题追踪 3. 错误消息使用中文,符合项目规范 4. 错误处理遵循DDD分层架构,错误类型定义在应用层 5. 错误码严格按照规范定义,不能多不能少