--- tags: [] aliases: - 🏗️ AI 辅助基础设施构建 SOP (v2.1) - [错误处理与响应篇] - 🏗️ AI 辅助基础设施构建 SOP (v2.0) - [错误处理与响应篇] - 🏗️ AI 辅助基础设施构建 SOP (v1.1) - [错误处理与响应篇] - 🏗️ AI 辅助基础设施构建 SOP (v1.0) - [错误处理与响应篇] date created: 星期三, 十二月 10日 2025, 12:34:57 凌晨 date modified: 星期三, 十二月 10日 2025, 11:55:08 中午 --- # 🏗️ AI 辅助基础设施构建 SOP (v2.1) - [错误处理与响应篇] **核心理念:** 1. **Contract First (契约优先):** 永远先定义对外暴露的 JSON 结构,再写内部 Go 结构体。 2. **DX Driven (体验驱动):** 在实现逻辑前,先写“伪代码”验证调用是否顺手。 3. **Atomic Delivery (原子交付):** 单次交互只生成一个文件,利用“上下文锚点”串联上下文。 --- ## 📋 准备工作:变量与架构确认 在使用以下 Prompt 前,请确认上下文: - `{语言/框架}`: Go 1.24+ / Gin - `{模块路径}`: - `internal/pkg/ecode` (Level 0: 错误码 + 错误实体 + 映射逻辑) - `internal/pkg/app` (Level 1: HTTP 响应封装,依赖 `ecode`) - `{架构约束}`: `ecode` 包零依赖;`app` 包依赖 `ecode`。 --- ## Phase 0: 原子化任务拆解 (The MECE Protocol) **目的:** 将大需求拆解为一组符合 MECE 原则的微任务清单。 ### 🤖 拆解者 Prompt (复制使用) ```Markdown 你现在是我的 **Tech Lead (技术负责人)**。 我们要实现 `{模块名称}` 模块。为了防止代码生成中断和逻辑混乱,请不要直接开始写代码。 请先执行 **“MECE 任务拆解”**: **1. 架构约束分析:** - 本模块遵循 Modular Clean Architecture。 - `internal/pkg/ecode`: 包含错误码常量、错误实体结构体、错误文案映射。**严禁依赖上层包**。 - `internal/pkg/app`: 包含 Gin 的 Response 封装。依赖 `ecode`。 **2. 原子化切分:** 请将开发工作拆解为 3-5 个“原子任务步”。 - 每个步骤必须针对**单个物理文件**。 - 步骤必须遵循依赖顺序(底层先于上层)。 **3. 输出格式:** 请输出一个 **Markdown Checklist (执行清单)**。 格式示例: - [ ] **Step 1: {文件名}** - {核心职责} (依赖: 无) - [ ] **Step 2: {文件名}** - {核心职责} (依赖: Step 1) … **模块需求:** 我们需要一套统一的 HTTP 错误处理机制,支持自定义业务错误码,统一返回 JSON 格式。 ``` --- ## Phase 0.5: API 签名锁定 (API Surface Lock) **目的:** 在实现具体逻辑前,强制锁定所有 Public 方法的签名,防止实现阶段出现参数不一致。 ### 🤖 Prompt 0.5: 生成接口定义 **[发送给 AI]:** ````markdown 在开始写代码前,请先为 `internal/pkg/app` 包定义 **Public API 签名 (Exported Functions)**。 请直接提供 `Responder` 接口定义或核心函数的函数头(无需函数体)。 **要求:** 1. **一致性:** 确认 `context` 参数的位置(建议统一作为第一个参数)。 2. **完整性:** 必须包含 `New`, `Success`, `Error` 以及我们刚才讨论的 `ErrorCtx` (处理 trace_id)。 3. **Go Doc:** 为每个方法写出符合 Go 标准的注释。 **期望输出示例:** ```go // Response wraps the gin.Context for unified JSON response. type Response struct { … } // New creates a new Response wrapper. func New(c *gin.Context) *Response { … } // Success sends a successful response with data. func (r *Response) Success(data any) { … } ``` ```` --- ## Phase 1: 契约定义 (Contract Definition) **目的:** 确立“对外口径”。 ### 🤖 Prompt 1: 定义 JSON 结构 (复制使用) ```Markdown 你现在是我的 **API 治理专家**。 请设计一套统一的 **HTTP 响应结构 (JSON Envelope)**。 **设计原则:** 1. **统一性:** 无论成功还是失败,Body 结构一致。 2. **字段要求:** 必须包含 `code` (int), `msg` (string), `data` (any), `trace_id` (string)。 **任务:** 请给出以下 3 种场景的 JSON 响应示例,并解释设计理由: - 场景 A: 成功返回对象。 - 场景 B: 成功返回空列表 (明确 `data` 是 `null` 还是 `[]`)。 - 场景 C: 业务错误 (如 Code 20001)。 **[关键补充约束]** 1. **安全性优先:** `app.Error(err)` 处理逻辑中,必须区分**用户可见文案**和**底层调试信息**。若 `err` 包含底层堆栈(如 SQL 错误),JSON 中的 `msg` 必须降级显示为 `ecode` 定义的通用文案(如 "Internal Error"),严禁透传底层 Error String。 2. **HTTP 状态码:** 本项目强制执行 **"HTTP 200 OK + Business Code"** 策略。除非 Gin 框架层崩溃,否则 HTTP Status 永远为 200。 3. **Trace ID:** 假设 `c.GetString("trace_id")` 可以获取 ID,请在 `app.New(c)` 时将其注入 Response 结构体。 ``` --- ## Phase 2: 体验验证 (DX Verification) **目的:** 模拟业务层调用,防止基础设施“反人类”。 ### 🤖 Prompt 2: 伪代码验证 (复制使用) ```Markdown JSON 结构已确认。 假设我们已经有了 `internal/pkg/ecode` 和 `internal/pkg/app`。 请写一段 Gin Handler 的 **伪代码 (Pseudo-code)**,展示开发者该如何使用它们。 **验证重点:** 1. **业务错误:** 如何返回 `ecode.New(20001, "…")`? 2. **响应封装:** 如何调用 `app.New(c).Success(data)`? 3. **代码简洁性:** 避免大量的 `if err != nil` 重复代码。 请展示最优雅的写法。 ``` --- ## Phase 3: 迭代式核心实现 (Iterative Implementation) **核心机制:** 这是一个**循环步骤**。请查看 Phase 0 生成的 Checklist,**逐个文件**执行。 ### 🔄 循环动作 A: 生成代码 **[用户动作]:** 复制 Checklist 中当前未完成的步骤(例如 "Step 1: 生成 ecode/code.go")。 **[发送 Prompt]:** ```Markdown 我们现在执行 **Step {N}**。 **任务目标:** {粘贴 Phase 0 Checklist 中的当前步骤描述} **上下文约束 (严禁修改):** 1. **JSON 契约:** `{粘贴 Phase 1 确认的 JSON}` 2. **DX 规范:** `{粘贴 Phase 2 确认的伪代码}` 3. **依赖控制:** 如果是 `ecode` 包,严禁引用 `app` 或 `gin`。 **输出要求:** 请仅生成该步骤对应的 `{文件名}` 源代码。不要生成测试代码。 **通用代码质量约束 (Linter Rules):** 1. **注释规范:** 所有 Exported (首字母大写) 的结构体、函数、常量必须包含符合 Go Doc 规范的注释。 2. **复杂度控制:** 确保 `gocyclo` (圈复杂度) 低于 10。如果逻辑复杂,请拆分为私有函数。 3. **错误检查:** 严禁忽略 error 返回值(如 `json.Marshal`),必须处理或 Log。 4. **Lint 检查:** 生成的代码必须能通过 `errcheck` 和 `staticcheck`。 ``` ### 🔄 循环动作 B: 上下文锚点 (Context Anchoring) **[用户动作]:** 代码生成并确认无误后,发送此 Prompt 以建立记忆锚点。 **[发送 Prompt]:** ```Markdown 已确认 `{文件名}` 代码无误。 请将该代码存入你的**短期记忆**,作为后续步骤的上下文依赖。 **不要重复输出它**。我们准备进入下一步。 ``` _(重复 A -> B,直到所有源码文件生成完毕)_ --- ## Phase 4: 极限防御测试 (Extreme Defensive Testing) **目的:** 模拟“最糟糕”的业务代码调用,确保基础设施不崩。 ### 🤖 Prompt 4: 生成红队测试用例 ```markdown 所有核心代码已生成。现在请为 `internal/pkg/app/response.go` 编写单元测试 `response_test.go`。 **请覆盖以下 4 个极端场景 (Test Cases):** 1. **Raw Error 降级:** - **场景:** 传入 `errors.New("db connection broken")` (非 ecode 类型)。 - **断言:** HTTP 状态码为 500 (或 200+Code 50000),Msg 为 "Internal Server Error" (严禁泄漏原始错误信息)。 2. **Double Response 防护:** - **场景:** 在同一个 Handler 中连续调用 `app.Success()` 两次。 - **断言:** 第二次调用应被忽略或记录 Warning 日志,且不应导致 Panic。 3. **Nil Data 安全:** - **场景:** 调用 `app.Success(nil)`。 - **断言:** JSON 中的 `data` 字段应为 `null` (或 `{}`,取决于契约),不应 Panic。 4. **并发 Map 读写:** - **场景:** 启动 100 个 Goroutine 并发调用 `ecode.GetMsg(code)`。 - **断言:** `test -race` 必须通过,无数据竞争。 请输出完整的 Test 代码。 ``` --- ## Phase 5: 最终验收 (SRE Review) **目的:** 模拟运维视角审查。 ### 🤖 Prompt 5: 找茬模式 (复制使用) ```Markdown 切换角色为 **SRE (站点可靠性工程师)**。 请审查上述所有代码(ecode + app)。 **风险排查:** 1. **Panic 风险:** 是否有未捕获的 Panic 点? 2. **监控盲区:** 当前的 Error Log 是否包含了足够的上下文(如 StackTrace)供排查? 3. **状态码混淆:** 我们采用了“HTTP 200 + 业务码”模式,请确认这是否会影响网关层的 5xx 告警配置? 请简要列出 2-3 个优化建议。 ```