Files
Inbox/Go项目实战/03_基础设施/01_错误处理/02_AI 辅助基础设施构建 SOP (v2.1) -错误处理与响应篇.md
2025-12-11 07:24:36 +08:00

248 lines
8.9 KiB
Markdown
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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.

---
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 个优化建议。
```