Skip to content

Commit

Permalink
fix: parse a stack without entry
Browse files Browse the repository at this point in the history
  • Loading branch information
alvis committed Jul 30, 2024
1 parent 608757a commit e0987aa
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 13 deletions.
41 changes: 28 additions & 13 deletions source/stack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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;
}
});
}
Expand All @@ -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}`;
}
Expand Down
22 changes: 22 additions & 0 deletions spec/stack.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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' +
Expand All @@ -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',
Expand Down

0 comments on commit e0987aa

Please sign in to comment.