name: bknd-debugging description: 用于排查Bknd问题、调试错误、修复常见问题或诊断为何某事不工作。覆盖CLI调试命令、错误代码、日志、常见问题和解决方案。
调试常见问题
使用CLI工具、错误分析和系统故障排除来诊断和修复Bknd常见问题。
先决条件
- Bknd项目在本地设置完成
- 终端/命令行访问权限
- 对HTTP状态码有基本理解
何时使用UI模式
- 在管理面板(
/admin)中检查数据 - 可视化验证实体模式
- 手动测试CRUD操作
- 检查用户/角色配置
何时使用代码模式
- 运行调试CLI命令
- 分析API响应错误
- 检查路由注册
- 检查配置路径
- 查看服务器日志
CLI调试命令
显示所有注册的路由
npx bknd debug routes
输出显示每个HTTP端点:
- API路由(
/api/data/*、/api/auth/*、/api/media/*) - 管理路由(
/admin/*) - 自定义Flow HTTP触发器
- 插件路由
使用时机:端点返回404,验证自定义路由是否注册。
显示内部路径
npx bknd debug paths
输出:
[PATHS] {
rootpath: '/path/to/bknd',
distPath: '/path/to/dist',
relativeDistPath: './dist',
cwd: '/your/project',
dir: '/path/to/cli',
resolvedPkg: '/path/to/package.json'
}
使用时机:配置文件未加载,路径解析问题。
CLI帮助
npx bknd --help
npx bknd run --help
npx bknd types --help
HTTP错误代码
| 代码 | 含义 | 常见原因 |
|---|---|---|
| 400 | 错误请求 | 无效JSON、缺少必需字段、验证错误 |
| 401 | 未授权 | 缺少/无效/过期的令牌 |
| 403 | 禁止访问 | 有效令牌但权限不足 |
| 404 | 未找到 | 错误端点、实体不存在、记录未找到 |
| 409 | 冲突 | 重复唯一字段、用户已存在 |
| 413 | 负载过大 | 文件上传超过body_max_size |
| 500 | 服务器错误 | 未处理的异常、数据库错误 |
常见问题与解决方案
配置文件未加载
症状: “配置文件无法解析”错误
诊断:
# 检查配置是否存在
ls bknd.config.*
# 检查当前目录
pwd
# 检查Bknd看到的路径
npx bknd debug paths
解决方案:
# 确保正确扩展名
mv bknd.config.js bknd.config.ts
# 显式指定
npx bknd run -c ./bknd.config.ts
# 检查支持的扩展名:.ts、.js、.mjs、.cjs、.json
数据库未持久化
症状: 服务器重启后数据消失
诊断:
# 检查是否使用内存模式
# 在启动输出中查找“使用内存模式”
npx bknd run
# 检查数据库文件
ls *.db
解决方案:
# 使用基于文件的数据库
npx bknd run --db-url "file:data.db"
# 不要使用内存模式
npx bknd run --memory # 数据会丢失!
# 在配置中验证:
# connection: { url: "file:data.db" } ✓
# connection: { url: ":memory:" } ✗
端口已被占用
症状: EADDRINUSE: 地址已被使用
诊断:
# 查找使用端口的进程
lsof -i :3000
# 或在Windows上
netstat -ano | findstr :3000
解决方案:
# 使用不同端口
npx bknd run --port 3001
# 终止现有进程
kill -9 <PID>
# 或在Windows上
taskkill /PID <PID> /F
身份验证不起作用
症状: 401错误、令牌未持久化、用户始终为null
诊断:
# 测试登录端点
curl -X POST http://localhost:3000/api/auth/password/login \
-H "Content-Type: application/json" \
-d '{"email":"test@example.com","password":"password"}'
# 检查身份验证配置
# 在响应错误中查找“策略”
解决方案:
- 身份验证未启用:
export default {
app: {
auth: { enabled: true }, // 必需!
}
}
- 错误策略路径:
# 密码身份验证端点:
POST /api/auth/password/login # ✓
POST /api/auth/login # ✗ 404
- JWT密钥未设置(生产环境):
auth: {
jwt: {
secret: process.env.JWT_SECRET, // 生产环境必需
}
}
- Cookie未设置(CORS):
auth: {
cookie: {
secure: false, // 仅对HTTPS设置为true
sameSite: "lax", // 不要设为“strict”以支持OAuth
}
}
- 令牌未持久化(前端):
const api = new Api({
host: "http://localhost:3000",
storage: localStorage, // 令牌持久化必需
});
权限被拒绝(403)
症状: 有效令牌但403禁止访问
诊断:
# 检查用户的角色
curl http://localhost:3000/api/auth/me \
-H "Authorization: Bearer <token>"
# 检查配置中的角色权限
解决方案:
- 防护未启用:
export default {
app: {
auth: {
guard: { enabled: true }, // 权限必需
}
}
}
- 无默认角色(匿名访问):
auth: {
guard: {
roles: {
anonymous: {
is_default: true, // 允许未身份验证访问
permissions: ["data.entity.read"],
}
}
}
}
- 角色缺少权限:
roles: {
user: {
permissions: [
"data.entity.read",
"data.entity.create", // 如果需要则添加
]
}
}
- 需要实体特定权限:
permissions: [
{ permission: "data.entity.read", entity: "posts" },
]
实体/记录未找到(404)
症状: 数据端点返回404
诊断:
# 列出所有实体
curl http://localhost:3000/api/data
# 检查实体名称(区分大小写)
curl http://localhost:3000/api/data/Posts # ✗
curl http://localhost:3000/api/data/posts # ✓
# 验证路由
npx bknd debug routes | grep data
解决方案:
- 模式未同步:
# 重启服务器以同步模式
npx bknd run
- 实体名称大小写不匹配:
// 模式定义小写
entity("posts", { ... })
// API调用必须完全匹配
api.data.readMany("posts"); // ✓
api.data.readMany("Posts"); // ✗ 404
- 记录不存在:
const result = await api.data.readOne("posts", 999);
if (!result.ok) {
console.log("未找到:", result.status); // 404
}
使用em()时的类型错误
症状: 使用模式对象时的TypeScript错误
问题: em()返回模式定义,而非可查询的EntityManager。
// 错误 - 这会失败
const schema = em({
posts: entity("posts", { title: text() }),
});
schema.repo("posts").find(); // ✗ 错误!
// 正确 - 使用SDK进行查询
const api = new Api({ url: "http://localhost:3000" });
await api.data.readMany("posts"); // ✓
对于直接数据库访问(仅服务器端):
const app = new App(config);
await app.build();
const posts = await app.em.repo("posts").findMany(); // ✓
模式同步问题
症状: 实体在代码中但不在数据库中,或反之
诊断:
# 检查管理面板 -> 模式视图
# 或直接查询
curl http://localhost:3000/api/system/schema
解决方案:
- 重启服务器 - 模式在启动时同步:
npx bknd run
- 强制同步(可能丢失数据):
options: {
sync: {
force: true, // 危险!可能删除表
}
}
- 检查模式 - 数据库模式忽略代码模式:
// 代码模式(默认) - 模式来自代码
mode: "code"
// 混合模式 - 合并代码和数据库
mode: "hybrid"
文件上传失败
症状: 413错误,上传静默失败
诊断:
# 检查文件大小
ls -la myfile.jpg
# 测试上传
curl -X POST http://localhost:3000/api/media/upload \
-H "Authorization: Bearer <token>" \
-F "file=@myfile.jpg"
解决方案:
- 文件过大:
media: {
body_max_size: 10 * 1024 * 1024, // 10MB
}
- 存储未配置:
media: {
adapter: {
type: "s3",
// ... S3配置
}
}
- 本地存储(仅开发):
import { registerLocalMediaAdapter } from "bknd/adapter/node";
const local = registerLocalMediaAdapter();
export default {
app: {
media: { adapter: local }
}
}
CORS错误
症状: 浏览器控制台中的“Access-Control-Allow-Origin”错误
诊断:
# 检查CORS头部
curl -I http://localhost:3000/api/data/posts \
-H "Origin: http://localhost:5173"
解决方案:
export default {
app: {
server: {
cors: {
origin: ["http://localhost:5173", "https://myapp.com"],
credentials: true, // 用于Cookie
}
}
}
}
用于开发(允许所有):
server: {
cors: {
origin: "*",
}
}
无头环境崩溃
症状: 无显示服务器上的spawn xdg-open ENOENT
解决方案:
npx bknd run --no-open
Windows ESM错误
症状: Windows上的ERR_UNSUPPORTED_ESM_URL_SCHEME
解决方案:
- 使用Node.js 18+
- 确保package.json中有
"type": "module" - 配置使用
.mjs扩展名
TypeScript类型未更新
症状: IDE显示旧类型,自动完成错误
解决方案:
# 重新生成类型
npx bknd types
# 重启TypeScript服务器(VS Code)
# Cmd/Ctrl + Shift + P -> "TypeScript: Restart TS Server"
# 清除缓存
rm -rf node_modules/.cache
调试脚本模式
创建一个调试助手以进行系统故障排除:
// debug.ts
import { Api } from "bknd/client";
async function debug() {
const api = new Api({ host: "http://localhost:3000" });
// 1. 检查服务器健康状态
console.log("=== 健康检查 ===");
const entities = await fetch("http://localhost:3000/api/data");
console.log("状态:", entities.status);
console.log("实体:", await entities.json());
// 2. 检查身份验证
console.log("
=== 身份验证检查 ===");
const me = await api.auth.me();
console.log("身份验证状态:", me.ok ? "已验证" : "未验证");
if (me.data) console.log("用户:", me.data);
// 3. 检查模式
console.log("
=== 模式检查 ===");
const schema = await fetch("http://localhost:3000/api/system/schema");
console.log("模式:", await schema.json());
// 4. 测试实体访问
console.log("
=== 实体访问 ===");
const posts = await api.data.readMany("posts", { limit: 1 });
console.log("帖子访问:", posts.ok ? "成功" : `失败(${posts.status})`);
}
debug().catch(console.error);
运行:
npx tsx debug.ts
日志模式
服务器端日志
// 在种子函数或插件中
options: {
seed: async (ctx) => {
console.log("[SEED] 启动中...");
console.log("[SEED] 实体:", Object.keys(ctx.em.entities));
try {
await ctx.em.mutator("posts").insertOne({ title: "测试" });
console.log("[SEED] 创建帖子");
} catch (e) {
console.error("[SEED] 错误:", e);
}
}
}
API响应日志
const api = new Api({
host: "http://localhost:3000",
verbose: true, // 记录所有请求/响应
});
// 或手动日志
const result = await api.data.readMany("posts");
console.log("请求结果:", {
ok: result.ok,
status: result.status,
data: result.data,
error: result.error,
});
带日志的自定义Fetcher
const api = new Api({
host: "http://localhost:3000",
fetcher: async (url, options) => {
console.log("→", options?.method || "GET", url);
const start = Date.now();
const response = await fetch(url, options);
console.log("←", response.status, `(${Date.now() - start}ms)`);
return response;
},
});
Flow/任务调试
HTTP触发器错误
同步模式在响应中返回错误:
{
"success": false,
"errors": [
{
"task": "fetchUser",
"error": "Failed to fetch user: 404 Not Found",
"timestamp": "2024-01-15T10:30:00Z"
}
]
}
任务错误处理
import { Task, Condition } from "bknd/flows";
const flow = new Flow("myFlow", [
mainTask,
errorTask.connect(mainTask, Condition.error()), // 处理错误
]);
验证清单
调试时按顺序检查这些:
-
服务器在运行吗?
curl http://localhost:3000/api/data -
配置加载了吗?
- 在启动日志中检查“从…使用配置”
-
模式同步了吗?
- 检查管理面板或
/api/system/schema
- 检查管理面板或
-
身份验证启用了吗?(如果需要)
- 检查配置中的
auth: { enabled: true }
- 检查配置中的
-
权限设置了吗?(如果403)
- 检查
guard: { enabled: true }和角色
- 检查
-
CORS配置了吗?(如果浏览器错误)
- 检查
server: { cors: {...} }
- 检查
应该做与不应该做
应该做:
- 首先检查服务器日志
- 使用
npx bknd debug routes处理404 - 验证实体名称完全匹配(区分大小写)
- 在调试前端之前用curl测试
- 在Api中使用
verbose: true进行请求日志 - 模式更改后重启服务器
不应该做:
- 假设
em()返回可查询的EntityManager - 在无头服务器上忘记
--no-open - 使用
:memory:数据库处理持久数据 - 在响应中跳过检查HTTP状态码
- 调试前端问题时忽略CORS
- 在生产环境中使用
sync: { force: true }
相关技能
- bknd-local-setup - 初始项目设置
- bknd-env-config - 环境变量配置
- bknd-setup-auth - 身份验证配置
- bknd-assign-permissions - 权限故障排除
- bknd-api-discovery - 探索可用端点