# 错误处理

| 错误场景 | 判断条件 | 处理方式 |
|---------|---------|---------|
| 会话失效 | message 含"会话"/"登录"/"token" | 停止当前步骤，向用户索取对应 token；默认仅在当前会话重试，另获明确同意后才写入 `config.json` |
| ID 语义不明确 | 数字未标注为 `uid`、`activity_center_id` 或 `apollo_activity_id` / `act_id` | 不调用接口，先询问用户确认映射 |
| 活动 ID 不一致 | Apollo `act_id` 与活动中心 `page_link.id` 不一致 | 停止流程，展示差异并要求修正 ID；不得进入 Step 3 |
| 用户不存在 | `code != 200` 或 `data.user_info` 为空 | 中断，报告"用户无效，终止测试" |
| 活动未找到 | 返回列表中无目标活动 | 请用户重新提供 `activity_center_id` |
| 活动未开始 | 当前时间 < `start_time` | 中断，展示活动开始时间 |
| 活动已结束 | 当前时间 > `end_time` | 中断，展示活动结束时间 |
| 用户确认活动不对 | 用户回复"不对"/"错误" | 请用户重新提供活动ID，从 Step 2a 重试 |
| 抽奖接口报错 | 接口返回非正常 code | 展示错误信息，停止循环，输出已抽部分的报告 |

## Token 配置说明

Token 存储在 `<skill-dir>/config.json`：

```json
{
  "tokens": {
    "minigame_backend": {
      "description": "小游戏后台 x-token（139.224.2.208:7008 和 106.14.144.130:7072 共用，走 snake-proxy.wepieoa.com 代理）",
      "x-token": ""
    },
    "apollo": {
      "description": "阿波罗 x-token（apollo-admin-api.wepie.com，与小游戏后台不同）",
      "x-token": ""
    }
  }
}
```

用户提供新 token 后，默认仅在当前会话中从失败步骤重试。只有用户对“持久化该 token”另行明确同意后，才更新 `config.json`；抽奖确认不能替代此授权。小游戏后台与 Apollo token 必须写入各自字段，不得互换。任何情况下都不得把 token 输出到消息、命令、日志或报告，且 `config.json` 权限必须保持为 `600`。
