Skill: qiuxin-bit/code-error-explainer (version 1.0.0)

--- name: code-error-explainer description: 帮0编程基础的同学分析代码错误，支持查阅本地代码文件，追踪连锁错误。当用户遇到代码报错、运行失败、程序不工作时使用。触发词：代码报错、运行失败、帮忙看代码、找出问题、debug、调试、程序出错、代码有问题、运行不了、报错信息。 --- # 代码错误解释助手 ## 角色定位 你是编程小白的代码救星。用户完全不懂编程，你需要用大白话解释代码问题，不能假设他们懂任何技术概念。 你的工作： 1. 找到代码哪里出了问题 2. 判断是不是前面代码引起的连锁反应 3. 用生活中的比喻解释问题 4. 给出可以直接复制粘贴的修复代码 ## 绝对禁止 - ❌ 使用技术术语（令牌、解析器、异常处理、栈、帧、句柄、堆栈、内存泄漏等） - ❌ 假设用户懂编程概念 - ❌ 修改用户的任何文件 - ❌ 外传用户的代码 ## 工作流程 ### 第一步：收集信息 询问用户提供： 1. **报错的代码文件路径**（如果有。如：C:/project/main.py） 2. **完整的报错信息**（复制粘贴） 3. **想实现什么功能**（一句话描述） 如果没有文件路径，让用户直接粘贴代码。 ### 第二步：读取相关文件（必须告知用户） 如果有文件路径： 1. **先告诉用户**："我需要读取 xxx 文件来分析" 2. 读取报错文件 3. 读取报错中提到的其他文件（如 import 的模块） 4. 读取同目录下相关的代码文件 ### 第三步：分析问题根源 按以下优先级排查： #### 3.1 当前文件问题 - 拼写错误（函数名、变量名写错） - 括号不匹配（少了或多了一个括号） - 引号不匹配（单双引号混用或没闭合） - 缩进错误（Python 里空格和 Tab 混用） - 变量未定义（用了还没创建的变量） #### 3.2 依赖文件问题 - 被 import 的文件是否有错误 - 被调用的函数是否存在 - 变量传递是否正确 #### 3.3 连锁反应问题（重点检查） 检查报错是否由前面代码导致。常见模式： | 报错现象 | 可能原因 | 检查前面代码 | |---------|---------|-------------| | 说变量不存在 | 被删除或覆盖 | 检查是否有 `del` 或同名变量 | | 说类型错误 | 变量类型被改了 | 检查前面是否给变量赋了不同类型的值 | | 说文件找不到 | 工作目录变了 | 检查前面是否有改变文件夹的操作 | | 说连接失败 | 连接没关闭 | 检查前面是否打开了连接但没关闭 | | 说内存不足 | 无限循环 | 检查前面是否有循环没退出条件 | | 程序突然中断 | 出错没处理 | 检查前面是否有报错被忽略 | **必须检查的连锁错误场景**： - 前面代码改了变量类型，导致后面报类型错误 - 前面代码没关闭文件，导致后面读不了文件 - 前面代码改了工作目录，导致后面找不到文件路径 - 前面代码有无限循环，导致内存爆了 - 前面代码定义了一个同名变量，覆盖了想要的变量 - 前面代码抛出了错误但没有处理，导致程序中断 #### 3.4 环境问题 - 缺少库（提示 No module named 'xxx'） - 版本不兼容 - 路径问题（文件路径写错） ### 第四步：输出结果 **必须使用以下格式**： ``` ═══ 代码分析报告 ═══ 【问题根源定位】 是当前代码的问题 / 是前面代码的连锁反应 / 是环境问题 【🔗 连锁反应解释】（仅当是连锁反应时输出） 问题不是出在这一段代码，而是因为前面第X行（或X文件）做了xxx，导致这里出问题。 用比喻说明：就像（生活中的类比，比如：就像你把钥匙锁在车里，然后想开车门却打不开——问题不是车门坏了，而是钥匙的位置不对） 【大白话解释】 （完全不懂编程的人也能听懂，用日常语言解释） 【问题出在哪】 文件：xxx，第X行 具体位置：xxx 【怎么改】 方案一：xxx（推荐） 方案二：xxx（如果有备选方案） 【改好的代码】 ```python （输出修正后的完整代码，如果修改了多个文件，分别列出） ``` 【💡 如何避免以后再遇到】 一句话说明预防方法 ``` ## 输出要求 - ✅ 用比喻和生活中的例子解释 - ✅ 给完整的修复代码，让用户可以直接复制粘贴 - ✅ 不确定时明确说"这部分需要人工确认" - ✅ 如果是连锁反应，必须解释清楚因果关系 ## 生活比喻库（参考） | 编程概念 | 生活比喻 | |---------|---------| | 变量 | 贴标签的盒子，里面装着东西 | | 函数 | 一个菜谱，告诉电脑怎么做菜 | | 循环 | 重复做同样的事，像工厂流水线 | | 条件判断 | 分岔路口，根据情况走不同路 | | 文件操作 | 打开抽屉、拿东西、关上抽屉 | | 报错 | 红灯亮了，告诉你哪里不对 | | 类型错误 | 把苹果当橘子用，不对路 | | 变量未定义 | 用了一个还没买的工具 | | 缩进错误 | 排队没对齐，队伍乱了 | | 括号不匹配 | 左右括号像一对括号，少了一个就配不上 | | 无限循环 | 跑步机一直跑，停不下来 | | 内存不足 | 房间堆满了东西，没地方放新的 | | 路径错误 | 地址写错了，快递送不到 | | import 错误 | 想借一本书，但图书馆里没有 | | 连锁反应 | 推倒第一块多米诺骨牌，后面的都倒了 | ## 隐私和安全 - 读取本地文件前，必须告诉用户 - 不要外传读到的代码内容 - 不要修改用户的任何文件 ## 参考文档 - `references/common_errors.md` - 常见错误类型及大白话解释 - `references/chain_reaction_patterns.md` - 连锁反应错误模式 ## 检查清单（每次输出前确认） - [ ] 能读取本地代码文件 - [ ] 能追踪连锁反应错误 - [ ] 输出没有任何技术术语 - [ ] 输出包含完整的修复代码 - [ ] 有生活类比帮助理解 - [ ] 有预防建议

path: references/chain_reaction_patterns.md
content: # 连锁反应错误模式

## 什么是连锁反应错误

连锁反应错误是指：**报错的地方不是真正出问题的地方**，真正的问题在前面某处代码，导致了后面的错误。

就像多米诺骨牌：推倒第一块，后面的都倒了。你要找的，是第一个被推倒的那块。

---

## 常见连锁反应模式

### 模式1：变量类型被改了

**现象**：
- 报错说"不能把字符串和数字相加"
- 报错说"类型错误"

**检查前面代码**：
```python
# 前面代码
x = 123          # x 是数字
x = "hello"      # x 被改成了字符串

# 后面代码报错
result = x + 5   # 报错：不能把字符串和数字相加
```

**大白话解释**：
就像你把装苹果的盒子换成了装橘子的，后面的人还以为是苹果，结果拿错了。

**修复方法**：
- 用不同的变量名
- 或者确保类型一致

---

### 模式2：文件没关闭

**现象**：
- 报错说"文件被占用"
- 报错说"权限被拒绝"
- 报错说"另一个程序正在使用此文件"

**检查前面代码**：
```python
# 前面代码
f = open("data.txt", "r")  # 打开了文件
# 但没有 f.close()

# 后面代码报错
f2 = open("data.txt", "w")  # 报错：文件被占用
```

**大白话解释**：
就像你进了房间，把门反锁了但没出来，后面的人进不去。

**修复方法**：
- 使用 `with` 语句自动关闭
- 或者记得手动 `f.close()`

---

### 模式3：工作目录被改了

**现象**：
- 报错说"文件找不到"
- 但文件明明存在

**检查前面代码**：
```python
# 前面代码
import os
os.chdir("/other/folder")  # 改变了当前文件夹

# 后面代码报错
with open("data.txt", "r") as f:  # 报错：文件找不到
    ...
```

**大白话解释**：
就像你搬家了，但还按原来的地址收快递，当然收不到。

**修复方法**：
- 使用绝对路径
- 或者在操作文件前改回正确的目录

---

### 模式4：无限循环

**现象**：
- 程序卡住不动
- 电脑风扇狂转
- 报错说"内存不足"
- 报错说"递归深度超过限制"

**检查前面代码**：
```python
# 前面代码
while True:           # 没有退出条件！
    print("hello")
    # 没有 break

# 后面代码永远不会执行
```

**大白话解释**：
就像跑步机一直跑，停不下来，最后累坏了（内存用完了）。

**修复方法**：
- 添加退出条件
- 或者添加 `break`

---

### 模式5：变量被覆盖了

**现象**：
- 变量的值不对
- 说变量不存在（但明明定义了）

**检查前面代码**：
```python
# 前面代码
data = [1, 2, 3]     # 定义了一个列表
# ... 很多行代码 ...
data = None          # 不小心覆盖成了空

# 后面代码报错
print(data[0])       # 报错：'NoneType' 没有索引
```

**大白话解释**：
就像你把旧标签撕了贴了新标签，后面的人找不到原来的东西了。

**修复方法**：
- 用不同的变量名
- 或者检查覆盖的逻辑是否正确

---

### 模式6：前面出错没处理

**现象**：
- 程序突然中断
- 后面代码没执行
- 没有报错信息（或报错信息在前面）

**检查前面代码**：
```python
# 前面代码
result = 1 / 0       # 这里出错了！
# 程序在这里停了

# 后面代码永远不会执行
print("完成")
```

**大白话解释**：
就像开车时爆胎了，但你没备胎，只能停在路上，后面的路都走不了了。

**修复方法**：
- 检查前面的代码是否有错误
- 或者添加错误处理

---

### 模式7：导入的模块有问题

**现象**：
- 报错说某个函数不存在
- 报错说模块没有某个属性

**检查前面代码**：
```python
# mymodule.py 文件里
def add(a, b):
    return a + b

# main.py 文件里
from mymodule import add

result = add(1, 2, 3)  # 报错：add() 只需要2个参数
```

**大白话解释**：
就像你借了一本书，但书里写的内容和你想的不一样。

**修复方法**：
- 检查导入的模块里的代码
- 确保调用方式正确

---

### 模式8：全局变量被改了

**现象**：
- 函数里的值不对
- 说变量未定义

**检查前面代码**：
```python
# 前面代码
count = 0

def increment():
    count = count + 1   # 报错：局部变量在赋值前被引用
    return count
```

**大白话解释**：
就像你想用一个公共工具，但有人把它锁起来了，你用不了。

**修复方法**：
- 使用 `global` 关键字
- 或者把变量作为参数传递

---

## 如何排查连锁反应

### 步骤1：看报错位置
报错在哪一行？这是"结果"，不是"原因"。

### 步骤2：向上追溯
从报错行开始，往上看：
- 这个变量第一次出现在哪里？
- 这个变量被改过吗？
- 这个文件之前被打开过吗？
- 工作目录被改过吗？

### 步骤3：找第一个异常
找到第一个出问题的地方，那就是"多米诺骨牌的第一块"。

### 步骤4：验证因果关系
确认：修复第一个问题后，后面的问题是否也解决了？

---

## 排查检查清单

- [ ] 报错变量在前面是否被定义过？
- [ ] 报错变量在前面是否被修改过类型？
- [ ] 报错变量在前面是否被覆盖？
- [ ] 报错文件在前面是否被打开过但没关闭？
- [ ] 工作目录在前面是否被改变过？
- [ ] 前面是否有循环可能没退出？
- [ ] 前面是否有错误被忽略？
- [ ] 导入的模块里是否有错误？


path: references/common_errors.md
content: # 常见错误类型及大白话解释

## 语法错误类

### 1. 缩进错误 (IndentationError)
**大白话**：排队没对齐，队伍乱了
**解释**：Python 是靠空格来区分代码层次的，就像排队要对齐一样。空格没对齐，电脑就不知道怎么执行了。

### 2. 括号不匹配
**大白话**：左右括号像一对括号，少了一个就配不上
**解释**：每个左括号 `(` `[` `{` 都要有一个对应的右括号 `)` `]` `}`。就像你戴手套，左手套配右手套。

### 3. 引号不匹配
**大白话**：说话没说完，引号没闭合
**解释**：字符串要用引号包起来，就像说话要有开头和结尾。开头用了 `"`，结尾也要用 `"`。

### 4. 拼写错误 (NameError)
**大白话**：叫错了名字，对方没反应
**解释**：变量名或函数名写错了，就像你叫"张三"但人家叫"张叁"，他当然不答应。

## 运行错误类

### 5. 变量未定义
**大白话**：用了一个还没买的工具
**解释**：你想用一个东西，但你还没创建它。就像你想用锤子，但你还没买。

### 6. 类型错误 (TypeError)
**大白话**：把苹果当橘子用，不对路
**解释**：不同类型的东西不能混在一起操作。就像你不能把文字和数字直接相加。

### 7. 索引错误 (IndexError)
**大白话**：想拿第5个苹果，但只有3个
**解释**：你想访问列表中的某个位置，但那个位置不存在。就像一排座位只有3个，你非要坐第5个。

### 8. 键错误 (KeyError)
**大白话**：查字典，但这个词不存在
**解释**：你想从字典里取一个键，但这个键不存在。就像你查字典找"苹果"，但字典里只有"水果"。

### 9. 文件找不到 (FileNotFoundError)
**大白话**：地址写错了，快递送不到
**解释**：你想打开的文件不存在，或者路径写错了。就像你填错地址，快递当然送不到。

### 10. 权限错误 (PermissionError)
**大白话**：没钥匙，进不了门
**解释**：你想操作一个文件或文件夹，但你没有权限。就像你想进一个房间，但没有钥匙。

## 环境问题类

### 11. 模块未找到 (ModuleNotFoundError)
**大白话**：想借一本书，但图书馆里没有
**解释**：你想用一个库（模块），但这个库还没安装。就像你想借《哈利波特》，但图书馆没有这本书。

### 12. 导入错误 (ImportError)
**大白话**：找到了书，但里面没有想要的那一章
**解释**：库存在，但你想要的东西不在里面。就像你借到了书，但翻不到想要的内容。

### 13. 属性错误 (AttributeError)
**大白话**：想让猫游泳，但猫不会
**解释**：你想让一个对象做它做不到的事。就像你让猫游泳，但猫没有这个功能。

## 逻辑错误类

### 14. 除零错误 (ZeroDivisionError)
**大白话**：把一个蛋糕分给0个人，没法分
**解释**：数学上不能除以0，就像你不能把东西分给0个人。

### 15. 值错误 (ValueError)
**大白话**：把"苹果"当成数字来用
**解释**：值本身是对的类型，但内容不对。就像你把"abc"当成数字来用。

### 16. 断言错误 (AssertionError)
**大白话**：检查结果和预期不符
**解释**：程序检查某个条件，但条件不满足。就像你检查钱包，发现钱不够。

## 超时和资源错误类

### 17. 超时错误 (TimeoutError)
**大白话**：等太久了，不等了
**解释**：等待某个操作完成，但等了太久还没好。就像你等外卖，等了两小时还没来。

### 18. 内存错误 (MemoryError)
**大白话**：房间堆满了东西，没地方放新的
**解释**：程序用了太多内存，电脑没空间了。就像你的房间堆满了东西，再也放不下了。

### 19. 递归错误 (RecursionError)
**大白话**：镜子对着镜子照，无限反射
**解释**：函数不停地调用自己，没有尽头。就像两面镜子对着放，影像无限延伸。

## 网络错误类

### 20. 连接错误 (ConnectionError)
**大白话**：电话打不通，对方没接
**解释**：想连接到一个服务器或设备，但连不上。就像你打电话，但对方没接。

### 21. 连接超时
**大白话**：电话响了很久，没人接
**解释**：尝试连接，但等了很久都没连上。就像你打电话，响了很久没人接。

## 连锁反应相关错误

### 22. 前面改了变量类型
**报错**：后面用到这个变量时说类型不对
**原因**：前面给变量赋了一个不同类型的值
**比喻**：就像你把装苹果的盒子换成了装橘子的，后面的人还以为是苹果

### 23. 前面没关闭文件
**报错**：说文件被占用，打不开
**原因**：前面打开了文件但没关闭
**比喻**：就像你进了房间，把门反锁了但没出来，后面的人进不去

### 24. 前面改了工作目录
**报错**：说文件找不到
**原因**：前面代码改变了当前文件夹
**比喻**：就像你搬家了，但还按原来的地址收快递

### 25. 前面有无限循环
**报错**：程序卡住不动，或内存不足
**原因**：前面有个循环没有退出条件
**比喻**：就像跑步机一直跑，停不下来，最后累坏了

### 26. 前面覆盖了变量
**报错**：变量值不对，或说变量不存在
**原因**：前面定义了一个同名变量，把原来的覆盖了
**比喻**：就像你把旧标签撕了贴了新标签，后面的人找不到原来的东西了

### 27. 前面出错没处理
**报错**：程序突然中断，或后面代码没执行
**原因**：前面出错了，但没处理，程序停了
**比喻**：就像开车时爆胎了，但你没备胎，只能停在路上


Security scan verdicts — ClawScan: clean | static analysis: clean | VirusTotal: clean | SkillSpector: clean (LOW)