# 钟馗异常处理策略

> 审查过程中遇到非致命错误时，必须主动报告而非静默跳过。

## 核心原则

1. **永远主动报告**：任何异常都必须输出上下文（文件路径 + 失败原因），禁止仅打印一行 `ERROR` 后静默退出
2. **尽力而为继续**：非致命错误不应中断审查流程，跳过问题文件/维度，继续审查其余部分
3. **降级而非放弃**：优先尝试备选方案，所有方案失败后才标记为不可审查
4. **错误信息结构化**：报告中的异常信息需包含文件路径、错误类型、已尝试的修复手段

## 异常分类与处理

### 1. 文件读取异常

| 异常 | 处理 | 降级链 |
|:---|:---|:---|
| 文件不存在 | 报告路径，跳过 | 无降级 |
| 权限不足 (PermissionError) | 报告路径 + 错误原因，跳过 | 尝试只读模式重试 1 次 |
| 文件被锁定 | 等待 1 秒后重试 1 次，仍失败则报告并跳过 | 无降级 |
| 路径是符号链接/快捷方式 | 解析真实路径后重新读取，无法解析则报告原路径 + 'unresolvable_symlink' | 解析 → 失败则跳过 |

### 2. 编码异常

```
尝试顺序：UTF-8 → GBK → Latin-1 → 失败
```

| 步骤 | 动作 | 失败后 |
|:---|:---|:---|
| 1 | `open(file, encoding='utf-8')` | → 步骤 2 |
| 2 | `open(file, encoding='gbk')` | → 步骤 3 |
| 3 | `open(file, encoding='latin-1')` | → 报告 `encoding_failed` |

Latin-1 作为兜底编码（永不出错），但会标记 `encoding_degraded: latin-1` 以提示审查结果可能不完整（非 ASCII 字符可能乱码）。

### 3. 脚本解析异常

| 异常 | 处理 |
|:---|:---|
| Python 语法错误 (SyntaxError) | 报告文件路径 + 行号 + 错误消息，标记 `parse_error`，对该文件跳过 S1-S12 检查 |
| 非文本脚本（二进制/编译文件） | 报告文件路径 + 类型，标记 `binary_script_skipped` |
| 脚本过大 (> 10MB) | 报告文件路径 + 大小，标记 `file_too_large`，跳过 |

### 4. Layer 2 模拟中断

| 中断原因 | 处理 |
|:---|:---|
| 工具调用超时 (> 30s) | 报告场景编号 + 'timeout'，该场景计 WARN |
| 模拟环境异常（工具调用返回 error） | 重试 1 次，仍失败则报告场景编号 + 错误原因，该场景计 FAIL |
| 上下文溢出（token 超限） | 报告场景编号 + 'context_overflow'，该场景跳过不计分 |

### 5. Layer 3 网络异常

| 异常 | 处理 |
|:---|:---|
| 请求超时 (> 10s) | 重试 1 次（间隔 3 秒），仍失败则标记 `unreachable`，该维度跳过 |
| DNS 解析失败 | 标记 `unreachable`，跳过 |
| HTTP 4xx/5xx | 不重试，报告状态码 + URL，标记 `http_error` |
| SSL 证书错误 | 标记 `ssl_error`，不降级为 HTTP（安全考虑） |
| 离线环境（无网络） | 一次性检测后标记 `offline_mode`，跳过所有 L3 网络维度 |

### 6. 空目录与无 Skill 文件

| 情况 | 处理 |
|:---|:---|
| 目录存在但无 SKILL.md | 报告"目标目录无 SKILL.md，非标准 Skill 结构" |
| 目录为空 | 报告"目标目录为空，无文件可审查" |
| SKILL.md 存在但为空 | 报告"SKILL.md 为空文件" |

## 报告中的异常格式

审查报告中异常信息以独立章节呈现：

```
### 审查异常
| 文件/维度 | 异常类型 | 详情 | 处理 |
|:---|:---|:---|:---|
| scripts/malformed.py | parse_error | SyntaxError at L23 | 跳过该文件脚本检查 |
| README.md | encoding_degraded | 使用 Latin-1 降级读取 | 非 ASCII 内容可能乱码 |
| Layer 3: 社区反馈 | unreachable | 网络不可用 | 该维度跳过 |
```

## 禁止的静默行为

以下行为明确禁止：

- ❌ `try: read_file() except: pass` — 吞掉异常不做任何报告
- ❌ `print("ERROR")` — 只有级别没有上下文
- ❌ 遇到编码错误时直接按二进制读取并假装成功
- ❌ 网络请求失败时直接返回空结果
- ❌ 脚本解析失败时对整个 Skill 判 0 分而非报告具体错误
