故障排查
从现象定位到配置、数据和执行阶段,排查本地开发、认证、支付、后台任务与部署问题。
遇到问题时,先确认“哪一步没有完成”,再决定修改什么。本章按照当前默认模板的实际流程分为六篇,同一条业务链上的问题放在一起,避免在认证、邮件、OAuth 或支付、Webhook 之间反复跳转。
从现象找到文章
| 现象 | 阅读文章 | 重点检查 |
|---|---|---|
| 安装失败、启动失败、构建失败、内容不更新 | 本地开发与构建 | Node.js、初始化、配置校验、内容生成 |
| 缺表、查不到数据、迁移失败、约束冲突 | 数据库与迁移 | 目标数据库、现有结构、迁移记录 |
| 登录跳转、验证码、邮件、Google 或 GitHub 登录失败 | 登录、邮件与 OAuth | Cookie、验证状态、发信模式、回调配置 |
| Checkout 失败、已经付款但未开通、Webhook 报错 | 支付与 Webhook | Stripe 连接、事件账本、交易、权益发放 |
| Queue 有消息但无结果、周期任务不执行、统计无数据 | 后台任务与统计 | 消费者分发、Event、Command、Cron |
| 首次部署中断、资源不存在、域名异常、线上仍是旧内容 | 部署、资源与域名 | 发布阶段、资源归属、运行配置、内容同步 |
一、先固定复现条件
记录运行环境、代码版本、访问地址、操作时间和最短复现步骤。比如“生产环境,使用普通账号购买 yearly 套餐,Stripe 已付款,刷新产品页后仍不可用”,比“支付坏了”更容易定位。
本地和生产应分别观察,不要用本地 D1 中没有记录来推断生产支付未入库,也不要在本地修改 .env 后直接验证线上行为。
| 证据 | 获取位置 | 用途 |
|---|---|---|
| 请求方法、路径、HTTP 状态和响应体 | 浏览器 Network | 区分前端未发请求、接口拒绝和服务端异常 |
| 第一条异常、请求时间、关联 ID | 本地终端、Worker 日志 | 找到失败步骤,关联后续处理 |
| Event ID、Checkout ID、内部执行 ID | 支付平台和应用日志 | 追踪同一笔业务,不凭时间相近猜测 |
| 配置项名称、资源名称和 ID | config/、wrangler.jsonc | 确认当前应用使用的目标 |
| 表结构、状态和记录时间 | 对应 D1 的只读查询 | 判断哪些步骤已经持久化 |
API 的 code 有时是数值结果码,有时属于第三方协议,也可能不存在。数值码可以在 src/errors.ts 中查询,不能把所有响应都当作完整的 APIResponse<T>。
分享排错信息时,隐藏 Cookie、Token、密钥、验证码和收件人信息。本地邮件预览会包含邮件正文,复制终端输出前也要检查。
二、先看诊断结果,再看业务结果
在初始化后的项目根目录,根据环境选择一个检查命令:
# 本地配置
npm run doctor# 生产配置与 Cloudflare 账号可用性
npm run doctor:remotedoctor 会检查配置、变量、Binding 名称和数据库目录等。doctor:remote 读取 .env.production,还会检查远程资源 ID 是否填写,以及当前身份是否能访问配置中的账户。
它们不是完整的线上探测工具。检查通过不意味着每个资源真实存在,也不意味着 Resend 已投递邮件、Stripe 已完成回调或 Queue 已执行任务。未启用的可选服务可能显示提示或警告,应结合当前要验证的功能判断。
三、按最后一个成功步骤继续查
典型支付流程是:
创建 Checkout → 用户付款 → Webhook 验签
→ 支付记录更新 → 创建业务 Event → 执行 Command → 用户获得访问能力如果已经收到正确的付款事件,就继续查看支付记录和权限处理,不必反复修改 Checkout 页面。如果还没有收到回调,就先解决回调地址、Secret 和投递问题。
后台任务同样如此。queue.send() 完成、消息被确认、Command 成功和外部服务最终完成是不同阶段,应分别验证。
四、修复后怎样确认
用同一个复现案例重新验证,并检查相关的失败场景。例如修正套餐映射后,既检查新付款能否开通,也检查重复回调是否没有重复发放。
代码修改后运行项目的 npm run verify。配置或服务商设置变更则还要实际验证对应业务,编译通过不能证明外部服务可用。
保留故障证据
不要为了消除报错而重置生产数据库、删除支付事件记录或更换 SAAS_SECRET。先确认故障发生的位置,再选择恢复方式。数据库重置会删除数据,主密钥变化可能让已有加密资料无法读取。
常见错误速查
| 错误或提示 | 下一步 |
|---|---|
Configuration validation failed at startup | 查看错误字段路径,检查配置和引用关系 |
no such table | 确认 D1 Binding、环境和迁移状态 |
Binding ... not found | 检查真实绑定,生成类型不会创建资源 |
redirect_uri_mismatch | 核对第三方平台和应用使用的完整回调地址 |
emailSendTooOften | 检查邮件发送配额与重复提交,不要持续重试 |
PAYMENT_NOT_CONFIGURED | 检查当前 Worker 的 Stripe 连接与密钥 |
WEBHOOK_BUSY | 查看该事件的处理租约与日志,不要删除账本 |
paymentsProductAlreadyPurchased | 检查套餐重复购买规则和已有购买记录 |
Command outcome needs manual review | 先核对外部效果,避免重复发送或重复发放 |
| 401、403、429 | 结合响应体区分会话、权限、来源校验和限流 |