Bun 的日志和错误处理机制如何?
Bun 作为基于 JavaScriptCore 引擎的高性能运行时,在日志和错误处理方面既保持了与 Node.js 的兼容性,又提供了自己的特色实现。下面从日志 API、错误捕获、服务端错误处理三个方面展开。
日志机制:console API 与配置增强
Bun 的日志系统以标准 console API 为核心,完全兼容浏览器和 Node.js 的用法:
- 标准 console 方法:Bun 支持
console.log()、console.error()、console.warn()、console.info()、console.debug()等全部标准方法。输出格式与 Node.js 一致,开发者无需修改现有代码即可迁移。 - 对象检查深度可配置:Bun 允许通过
bunfig.toml或 CLI 参数调整console.log()输出嵌套对象的深度,默认为 2 层:
toml# bunfig.toml console.depth = 4
或通过命令行指定:
bashbun --console-depth 4 run index.ts
这对于调试深层嵌套对象非常实用,避免在 Node.js 中频繁使用 JSON.stringify 的繁琐操作。
- Bun.inspect 精细化输出:Bun 提供
Bun.inspect()方法,支持语法高亮的格式化输出,特别适合错误对象的详细展示:
javascriptconst err = new Error("Something went wrong"); console.log(Bun.inspect(err, { colors: true }));
Bun.inspect 会输出错误消息、堆栈跟踪以及出错位置的源代码预览,比 Node.js 默认的 console.log(err) 提供更丰富的上下文信息。
- stdout/stderr 作为 BunFile:Bun 将标准输出和标准错误暴露为
Bun.stdout和Bun.stderr,类型为BunFile。这意味着可以直接用文件操作 API 写入日志:
javascriptawait Bun.write(Bun.stdout, "自定义日志输出\n");
- 调试环境变量:通过设置
BUN_CONFIG_VERBOSE_FETCH=1,Bun 会自动记录所有fetch()和node:http发出的网络请求,方便排查网络问题,无需手动添加日志:
bashBUN_CONFIG_VERBOSE_FETCH=1 bun run server.ts
错误处理机制:堆栈跟踪与服务端容错
Bun 的错误处理建立在 JavaScript 标准异常模型之上,但在堆栈跟踪和服务端错误边界方面有独特的实现。
- V8 兼容的堆栈跟踪:Bun 使用 JavaScriptCore 引擎,但将
error.stack格式化为与 V8 一致的格式,确保依赖 V8 堆栈格式的库(如 Sentry)能正常工作。同时实现了完整的 V8 Stack Trace API:
javascript// 捕获自定义堆栈跟踪 function myFunction() { const err = new Error("custom"); Error.captureStackTrace(err, myFunction); console.log(err.stack); } // 自定义堆栈格式化 Error.prepareStackTrace = (err, callsites) => { return callsites.map(c => `${c.getFileName()}:${c.getLineNumber()}`).join("\n"); };
-
未处理异常的源码预览:当未捕获的异常或 Promise 拒绝发生时,Bun 会自动打印出错位置的源代码片段,而不是仅显示堆栈文本。这让定位问题更加直观。
-
Sourcemap 自动映射:Bun 对所有转译文件自动生成和提供 sourcemap。在堆栈跟踪中点击文件路径,可以直接跳转到原始 TypeScript 或 JSX 源码位置,而非转译后的代码。
Bun.serve 的错误边界
HTTP 服务是 Bun 的核心使用场景,Bun.serve 提供了专门的 error 回调来处理请求处理过程中的异常:
- error 回调:当
fetch函数抛出异常时,Bun 会调用error回调,该回调应返回一个Response对象:
javascriptBun.serve({ fetch(req) { throw new Error("Something went wrong"); }, error(error) { return new Response(`Error: ${error.message}`, { status: 500, headers: { "Content-Type": "text/plain" }, }); }, });
- 开发模式错误页面:设置
development: true后,Bun 会在浏览器中展示内置的错误详情页面,包含堆栈跟踪和源码高亮:
javascriptBun.serve({ development: true, fetch(req) { throw new Error("debug me"); }, });
- Bun.file 流式响应的错误陷阱:当
Bun.file()作为流式响应的一部分出错时,错误无法通过fetch内部的try/catch捕获。这类错误只能由error回调统一处理:
javascriptBun.serve({ fetch(req) { try { const file = Bun.file("not-exist.txt"); return new Response(file); // 文件不存在时,try/catch 无法捕获 } catch (e) { // 这里不会执行 return new Response("Not found", { status: 404 }); } }, error(error) { // 必须在这里处理 Bun.file 的错误 return new Response("File not found", { status: 404 }); }, });
这是一个容易踩坑的地方:流式响应的错误发生在 fetch 返回之后,因此 try/catch 无法拦截。
- 动态更新处理器:使用
server.reload()可以在不停机的情况下更新fetch和error处理函数:
javascriptconst server = Bun.serve({ fetch(req) { return new Response("v1"); }, error(err) { return new Response("error v1", { status: 500 }); }, }); // 热更新处理逻辑 server.reload({ fetch(req) { return new Response("v2"); }, error(err) { return new Response("error v2", { status: 500 }); }, });
生产环境的日志与错误策略
在生产环境中,仅依赖 console 输出不足以支撑可观测性需求,需要结合第三方工具:
- 结构化日志:推荐使用社区库如 Pino(通过
bun-logger等封装)实现 JSON 格式的结构化日志,便于日志平台采集和分析:
javascriptimport pino from "pino"; const logger = pino({ level: process.env.LOG_LEVEL || "info" }); logger.info({ userId: "user123" }, "User login");
- 错误监控集成:Sentry 官方提供 Bun SDK,支持异常捕获和结构化日志:
javascriptimport * as Sentry from "@sentry/bun"; Sentry.init({ dsn: process.env.SENTRY_DSN, enableLogs: true, }); // 全局异常捕获 process.on("uncaughtException", (error) => { Sentry.captureException(error); });
- 日志级别控制:在
bunfig.toml中可以为bun install设置日志级别(debug/warn/error),但运行时日志级别需通过环境变量自行管理:
javascriptconst LOG_LEVEL = process.env.LOG_LEVEL || "info"; const levels = { debug: 0, info: 1, warn: 2, error: 3 }; function log(level, message) { if (levels[level] >= levels[LOG_LEVEL]) { console.log(`[${level.toUpperCase()}] ${message}`); } }
- 敏感信息过滤:错误日志应避免泄露密码、API Key 等敏感字段,在写入日志前做脱敏处理:
javascriptfunction sanitize(obj) { const safe = { ...obj }; for (const key of ["password", "apiKey", "secret"]) { if (key in safe) safe[key] = "****"; } return safe; } console.error("Request failed:", sanitize(context));
Bun 的日志和错误处理机制以标准 console API 为基础,通过 Bun.inspect、V8 兼容堆栈跟踪、Bun.serve 的 error 回调等特性提供了更强的调试能力和容错设计。理解 Bun.file 流式响应的错误边界、善用 BUN_CONFIG_VERBOSE_FETCH 调试网络请求、以及在生产环境集成 Pino 或 Sentry,是实际项目中的关键实践。