diff --git a/tracers.ts/src/context/tracer-context.ts b/tracers.ts/src/context/tracer-context.ts index adef36a..cfd856b 100644 --- a/tracers.ts/src/context/tracer-context.ts +++ b/tracers.ts/src/context/tracer-context.ts @@ -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) => { + 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();