diff --git a/source/stack.ts b/source/stack.ts index c53e551..6f032d5 100644 --- a/source/stack.ts +++ b/source/stack.ts @@ -29,8 +29,10 @@ export interface StackLocationBlock { export type StackBlock = StackDescriptionBlock | StackLocationBlock; +const SECOND_PART_START = 6; +const THIRD_PART_START = 10; const stackLineExpression = - /(\s*at (.+) \((.+):([0-9]+):([0-9]+)\))|(^(\w+):\s*([\w\W]*?)(\s*\n\s+))/gm; + /(\s*at (.+) \((.+):([0-9]+):([0-9]+)\))|(\s*at (.+):([0-9]+):([0-9]+))|(^(\w+):\s*([\w\W]*?)(\s*\n\s+))/gm; /** * parse a stack into its components @@ -40,21 +42,32 @@ const stackLineExpression = export function disassembleStack(stack: string): StackBlock[] { const matches = [...stack.matchAll(stackLineExpression)]; - return matches.map(([, , entry, path, line, column, , name, message]) => { - if (entry && path && line && column) { + return matches.map((parts) => { + const [, entry1, path1, line1, column1] = parts.slice(1, SECOND_PART_START); + const [, path2, line2, column2] = parts.slice( + SECOND_PART_START, + THIRD_PART_START, + ); + const [, name, message] = parts.slice(THIRD_PART_START); + + if (entry1 && path1 && line1 && column1) { return { type: 'location', - entry, - path, - line: parseInt(line), - column: parseInt(column), + entry: entry1, + path: path1, + line: parseInt(line1), + column: parseInt(column1), } as StackLocationBlock; - } else { + } else if (path2 && line2 && column2) { return { - type: 'description', - name, - message, - } as StackDescriptionBlock; + type: 'location', + entry: '', + path: path2, + line: parseInt(line2), + column: parseInt(column2), + } as StackLocationBlock; + } else { + return { type: 'description', name, message } as StackDescriptionBlock; } }); } @@ -68,7 +81,9 @@ export function assembleStack(stacks: StackBlock[]): string { return stacks .map((stack) => { if (stack.type === 'location') { - return ` at ${stack.entry} (${stack.path}:${stack.line}:${stack.column})`; + return stack.entry + ? ` at ${stack.entry} (${stack.path}:${stack.line}:${stack.column})` + : ` at ${stack.path}:${stack.line}:${stack.column}`; } else { return `${stack.name}: ${stack.message}`; } diff --git a/spec/stack.spec.ts b/spec/stack.spec.ts index 6c41c9a..bcf344d 100644 --- a/spec/stack.spec.ts +++ b/spec/stack.spec.ts @@ -18,6 +18,9 @@ import { assembleStack, disassembleStack } from '#stack'; import type { StackBlock } from '#stack'; const stack = + 'Error0: message0\n' + + ' at /src0:0:0\n' + + ' at file:///src1:1:1\n' + 'Error1: message1\n' + ' at entry1 (src1:1:0)\n' + ' at entry2 (src2:2:0)\n' + @@ -26,6 +29,25 @@ const stack = ' at entry4 (src4:4:0)'; const components: StackBlock[] = [ + { + type: 'description', + name: 'Error0', + message: 'message0', + }, + { + type: 'location', + entry: '', + path: '/src0', + line: 0, + column: 0, + }, + { + type: 'location', + entry: '', + path: 'file:///src1', + line: 1, + column: 1, + }, { type: 'description', name: 'Error1',