问题排查
定位常见的安装、集成、内容与部署故障。
先确认失败边界属于 Vite 构建、Worker runtime、D1、provider API 还是浏览器,再
一次只修改一个配置平面。本地从 .env 可用,不代表生产 Worker 已配置。
首轮检查
pnpm check
pnpm test
pnpm build然后确认当前 origin、Worker 日志(pnpm wrangler tail),以及问题发生在本地还是
远端。不要把远端 migration 或 secret 轮换当作猜测式第一步。
安装、Vite 与路由
| 现象 | 可能原因 | 安全修复 |
|---|---|---|
| 找不到命令/script | 包管理器错误或使用了不存在的 script | pnpm install;只用 package.json 中的 dev、build、preview、deploy |
fumadocs-mdx:collections/* import 失败 | .source 生成内容过期 | 停止 dev,必要时只删除生成的 .source,重新 pnpm dev/pnpm build |
| 路由文件存在但应用找不到 | 路由树过期或文件命名不符合约定 | 重启 Vite,并修正 src/routes 下文件 |
| 路由树修改消失 | 手改了 src/routeTree.gen.ts | 撤销手改,修改 route file;不要编辑生成树 |
Creem 的 node:crypto/Buffer 报错 | 缺少 nodejs_compat | 恢复 wrangler.jsonc 的 compatibility flag 并重建 |
Worker 配置与 binding
DB 与 UPLOADS 来自 wrangler.jsonc binding。若 undefined,核对 binding 名称/
资源,并在请求期间通过 cloudflare:workers 的 env 读取。不要从 process.env
读取它们,也不要在模块初始化时捕获。
| 现象 | 可能原因 | 安全修复 |
|---|---|---|
| 本地可用,部署后 secret 缺失 | .env/.dev.vars 不会上传 | pnpm wrangler secret put NAME 后重新部署 |
BETTER_AUTH_URL 仍是 localhost/旧域名 | 生产非 secret var 过期 | 把 wrangler.jsonc vars 改为准确部署 origin |
| 产品/模型/demo 改动不生效 | 构建后才修改 VITE_* | 在构建环境设置并重建/部署 |
| D1/R2 资源错误 | 各环境 binding ID/名称不一致 | 对照 wrangler.jsonc、Cloudflare 资源与部署配置 |
D1 与 Drizzle
| 现象 | 原因 | 修复 |
|---|---|---|
| 本地注册提示表不存在 | Miniflare D1 未执行 migration | pnpm db:migrate:local |
| 生产 schema 过期 | 只执行了本地 migration | 备份并审查后运行 pnpm db:migrate |
| SQL 与 schema 不符 | 改 schema 后未重新生成 | pnpm db:generate,审查 drizzle/,先本地后远端 |
| Drizzle 要求 PostgreSQL/连接 URL | 使用了其他模板说明 | 使用 D1/SQLite 与 DB binding;没有 DATABASE_URL |
建议的 drizzle-kit push 失败/绕过历史 | 工作流错误 | 使用生成并提交的 SQL migration,不要使用 drizzle-kit push |
| Transaction API 失败 | D1 不支持交互式 transaction | 使用 db.batch()/幂等语句并处理部分失败 |
Better Auth 与 OAuth
- **登录循环或 cookie 失败:**确保
BETTER_AUTH_URL与公开 scheme/host/port 完全 一致,生产使用 HTTPS,代理不会意外改变 origin。 - **OAuth callback mismatch:**provider callback 为
<origin>/api/auth/callback/github或/google;域名变化时同步更新。 - **受保护 API 仍可访问:**页面
beforeLoad不够,每个敏感 handler 都要重查 session/role。 - **本地注册无法完成:**执行本地 D1 migration 并配置 Resend;或只为明确的本地 开发有意识调整验证行为。
Resend 与联系表单
无邮件时检查 RESEND_API_KEY、发件域名验证与
websiteConfig.mail.fromEmail,查看 Resend 返回错误和控制台。当前
sendEmail() 返回结构化失败,但 auth/contact caller 并非都传播它,所以成功页面
不代表已投递。增加不含收件人或正文的安全日志与监控。
Creem 支付
| 现象 | 检查项 |
|---|---|
| Checkout 产品错误/缺失 | VITE_CREEM_PRODUCT_PRO_MONTHLY/_PRO_YEARLY/_LIFETIME;改后重建 |
| API 命中错误环境 | CREEM_SERVER_IDX 必须与 API key 配套 |
| Webhook 签名失败 | 原始 payload、CREEM_WEBHOOK_SECRET 与 provider signature header |
| 支付成功但 D1 未更新 | Webhook 必须是 /api/payment/notify/creem,远端 migration 已执行,并检查 Worker 日志 |
| Dashboard 显示无关订阅 | 订阅页仍是 mock;连接 /api/user/subscription |
R2 上传
- **
UPLOADSundefined:**创建并绑定 bucket,保持请求期env.UPLOADS访问。 - **上传 401:**接口要求 Better Auth session。
- **上传 400:**发送名为
files的FormData;当前最多五个、单个 5 MB,MIME 为image/*。 - **读取 404:**确认返回 key 位于同一个本地/远端 bucket。
- **接受不安全内容:**MIME metadata 不等于签名校验;增加解码/magic-byte 与尺寸策略。
OpenAI 与 Replicate
| 现象 | 可能原因/修复 |
|---|---|
| Chat 立即返回 400 | 检查 OPENAI_API_KEY、body 结构与模型可用性,安全查看 Worker 错误 |
| 搜索开关没有 source | 它选择 search-preview model,不是自定义 tool;只有模型返回时才有 source |
| 媒体提示 provider 未配置 | 本地/生产设置 REPLICATE_API_TOKEN,重启/部署 |
| 轮询不结束 | 检查 Replicate task;把 canceled 当终态,并核对输出解析/模型映射 |
| 输出之后消失 | Provider URL 未持久化;把成功结果复制到 R2 |
| AI 账单异常 | 公开接口尚无限额/限流;开放前加固 |
内容与 i18n
- **文档不在侧栏:**加入正确
meta.json,并确认 MDX 存在。 - **中文文档缺失/fallback:**添加
slug.zh.mdx;当前模板多数文档仍只有英文。 - **
/en/*重定向:**这是预期行为,默认英文 canonical 不带前缀;中文用/zh/*。 - **切换语言回首页:**当前
LanguageToggle会去所选语言根路径;如需保留页面, 改为 localize 当前路径。 - **博客/法律正文未翻译:**这些 loader 当前在多语言路由间共用一套 MDX。
仍无法解决
记录最小复现、准确命令/请求、本地或部署环境、脱敏错误、Worker 日志时间与相关
配置平面。不要公开 .env、Wrangler secret、OAuth 凭据、webhook payload 或用户
数据。
