diff --git a/src/utils/result.ts b/src/utils/result.ts index 589908f1..bb6eab20 100644 --- a/src/utils/result.ts +++ b/src/utils/result.ts @@ -14,10 +14,15 @@ * (`ApiError extends Error`),仓库 `Result.wrap` 捕获后用 `toError` 规范化, * 调用方能可靠地 `instanceof ApiError` / `error.message` 访问错误信息。 */ +import { Logger } from "./logger"; + export type Result = | { readonly success: true; readonly data: T } | { readonly success: false; readonly error: Error }; +/** 仓库层 Result.wrap 专用 logger —— 自动带 component: "Result" 标签 */ +const log = new Logger("Result"); + export const Result = { /** 构造成功结果。 */ ok(data: T): Result { @@ -49,12 +54,24 @@ export const Result = { /** * 捕获异步 thunk 的异常并包装成 `Result`。仓库内主要用这个把 * `*Api` 调用从「throw 风格」桥接到「Result 风格」。 + * + * 错误处理策略(重点): + * 1. 捕获后用 `toError` 规范化(保留 .stack / .code / .status 等字段) + * 2. **用 Logger 记录**(带 stack + component=Result 标签)—— 调试 dev 控制台可见, + * 生产环境走 JSON pipeline 接入日志平台 + * 3. **不**重新抛出 —— 调用方拿到的永远是 `Result`(throw 风格调用方可在 + * 最外层显式 `throw Result.unwrap(r)`) */ async wrap(thunk: () => Promise): Promise> { try { return Result.ok(await thunk()); } catch (e) { - return Result.err(e); + const err = toError(e); + log.error( + { err, stack: err.stack, type: err.constructor.name }, + "Result.wrap caught exception", + ); + return Result.err(err); } }, } as const;