feat(tracer-context): 添加scope方法以支持追踪异步错误

新增scope方法用于包裹异步或同步代码块,自动捕获错误并记录到上下文中。同时将dump方法重命名为flush以更准确描述其行为(清空并输出指令序列)。重构内部数据结构,将commands和error统一管理在scopeResult对象中。
This commit is contained in:
2026-02-22 22:37:06 +08:00
parent 0e61e4f5b9
commit 8894458f4c

View File

@@ -1,35 +1,74 @@
import type { TracerCommand } from '../types';
const createTracerContext = () => {
const commands: TracerCommand[] = [];
type Error = {
stack?: string;
};
// if (typeof process !== 'undefined' && typeof process.on === 'function') {
// process.on('exit', () => {
// if (commands.length > 0) {
// console.log(commands);
// }
// });
// }
type ScopeResult = {
// 记录指令序列
commands: TracerCommand[];
// 记录错误信息
error: Error;
// 检查是否多次调用scope
scoping: boolean;
};
const createTracerContext = () => {
const scopeResult: ScopeResult = {
commands: [],
error: {},
scoping: false,
};
const command = (command: TracerCommand) => {
scopeResult.commands.push(command);
};
// TODO: 输出指令序列和错误信息
const flush = () => {
console.log('输出指令序列');
const { commands, error } = scopeResult;
console.log(JSON.stringify({ commands, error }, null, 2));
scopeResult.commands.length = 0;
scopeResult.error.stack = undefined;
};
const getTracerContext = () => {
const command = (command: TracerCommand) => {
commands.push(command);
};
// TODO: 输出指令序列
const dump = () => {
return commands;
};
return {
command,
dump,
flush,
};
};
const scope = (routine: () => void | PromiseLike<void>) => {
if (scopeResult.scoping) {
throw new Error('[TracerContext] Detect multiple scope.');
}
scopeResult.scoping = true;
// 如果routine是同步函数那可能会抛出同步错误所以需要用try-catch包裹
try {
const promise = Promise.resolve(routine());
promise
.catch((err) => {
console.log('异步错误');
console.error(err);
scopeResult.error.stack = (err as Error).stack;
})
.finally(() => {
flush();
});
} catch (err) {
console.log('同步错误');
console.error(err);
scopeResult.error.stack = (err as Error).stack;
flush();
}
};
return {
getTracerContext,
scope,
};
};
export const { getTracerContext } = createTracerContext();
export const { getTracerContext, scope } = createTracerContext();