创建仓库
This commit is contained in:
247
Go项目实战/03_基础设施/01_错误处理/02_AI 辅助基础设施构建 SOP (v2.1) -错误处理与响应篇.md
Normal file
247
Go项目实战/03_基础设施/01_错误处理/02_AI 辅助基础设施构建 SOP (v2.1) -错误处理与响应篇.md
Normal file
@@ -0,0 +1,247 @@
|
||||
---
|
||||
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 个优化建议。
|
||||
```
|
||||
Reference in New Issue
Block a user