Skip to content

Commit c58f1cf

Browse files
committed
improved the stacktrace location regex to handle various location patterns
1 parent 5798ee8 commit c58f1cf

File tree

2 files changed

+70
-4
lines changed

2 files changed

+70
-4
lines changed

Diff for: packages/logger/src/formatter/LogFormatter.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ abstract class LogFormatter implements LogFormatterInterface {
9595
}
9696

9797
const stackLines = stack.split('\n');
98-
const regex = /\((.*):(\d+):(\d+)\)\\?$/;
98+
const regex = /\(([^)]*?):(\d+):(\d+)\)\\?$/;
9999

100100
let i;
101101
for (i = 0; i < stackLines.length; i++) {

Diff for: packages/logger/tests/unit/formatter/PowertoolsLogFormatter.test.ts

+69-3
Original file line numberDiff line numberDiff line change
@@ -312,7 +312,7 @@ describe('Class: PowertoolsLogFormatter', () => {
312312
});
313313

314314
describe('Method: getCodeLocation', () => {
315-
test('when the stack IS present, it returns a datetime value ISO 8601 compliant', () => {
315+
test('when the stack IS present, it returns a location for a stackframe with absolute file path', () => {
316316
// Prepare
317317
const formatter = new PowertoolsLogFormatter();
318318
const stack =
@@ -327,7 +327,73 @@ describe('Class: PowertoolsLogFormatter', () => {
327327
expect(errorLocation).toEqual('/home/foo/bar/some-file.ts:154');
328328
});
329329

330-
test('when the stack IS NOT present, it returns a datetime value ISO 8601 compliant', () => {
330+
test('when the stack IS present, it returns a location for a stackframe ending with an optional backslash', () => {
331+
// Prepare
332+
const formatter = new PowertoolsLogFormatter();
333+
const stack =
334+
'Error: Reference Error!\n' +
335+
' at /home/foo/bar/file-that-threw-the-error.ts:22:5\n' +
336+
' at SomeOther.function (/home/foo/bar/some-frame-with-ending-backslash.ts:154:19)\\';
337+
338+
// Act
339+
const errorLocation = formatter.getCodeLocation(stack);
340+
341+
// Assess
342+
expect(errorLocation).toEqual(
343+
'/home/foo/bar/some-frame-with-ending-backslash.ts:154'
344+
);
345+
});
346+
test('when the stack IS present, it returns a location for a path containing multiple colons', () => {
347+
// Prepare
348+
const formatter = new PowertoolsLogFormatter();
349+
const stack =
350+
'Error: The message failed to send\n' +
351+
'at REPL2:1:17\n' +
352+
'at Script.runInThisContext (node:vm:130:12)\n' +
353+
'... 7 lines matching cause stack trace ...\n' +
354+
'at [_line] [as _line] (node:internal/readline/interface:886:18) {\n' +
355+
'[cause]: Error: The remote HTTP server responded with a 500 status\n' +
356+
' at REPL1:1:15\n' +
357+
' at Script.runInThisContext (node:vm:130:12)\n' +
358+
' at REPLServer.defaultEval (node:repl:574:29)\n' +
359+
' at bound (node:domain:426:15)\n' +
360+
' at REPLServer.runBound [as eval] (node:domain:437:12)\n' +
361+
' at REPLServer.onLine (node:repl:902:10)\n' +
362+
' at REPLServer.emit (node:events:549:35)\n' +
363+
' at REPLServer.emit (node:domain:482:12)\n' +
364+
' at [_onLine] [as _onLine] (node:internal/readline/interface:425:12)\n' +
365+
' at [_line] [as _line] (node:internal/readline/interface:886:18) \n';
366+
367+
// Act
368+
const errorLocation = formatter.getCodeLocation(stack);
369+
370+
// Assess
371+
expect(errorLocation).toEqual('node:vm:130');
372+
});
373+
374+
test('when the stack IS present, it returns a location for a nested path', () => {
375+
// Prepare
376+
377+
const formatter = new PowertoolsLogFormatter();
378+
const stack =
379+
'Error: unknown\n' +
380+
'at eval (eval at <anonymous> (file:///home/foo/bar/some-file.ts:1:35), <anonymous>:1:7)\n' +
381+
'at <anonymous> (/home/foo/bar/file-that-threw-the-error.ts:52:3)\n' +
382+
'at ModuleJob.run (node:internal/modules/esm/module_job:218:25)\n' +
383+
'at async ModuleLoader.import (node:internal/modules/esm/loader:329:24)\n' +
384+
'at async loadESM (node:internal/process/esm_loader:28:7)\n' +
385+
'at async handleMainPromise (node:internal/modules/run_main:113:12)\n';
386+
387+
// Act
388+
const errorLocation = formatter.getCodeLocation(stack);
389+
390+
// Assess
391+
expect(errorLocation).toEqual(
392+
'/home/foo/bar/file-that-threw-the-error.ts:52'
393+
);
394+
});
395+
396+
test('when the stack IS NOT present, it returns an empty location', () => {
331397
// Prepare
332398
const formatter = new PowertoolsLogFormatter();
333399
const stack = undefined;
@@ -339,7 +405,7 @@ describe('Class: PowertoolsLogFormatter', () => {
339405
expect(errorLocation).toEqual('');
340406
});
341407

342-
test('when the stack IS NOT present, it returns a datetime value ISO 8601 compliant', () => {
408+
test('when the stack IS present, if a stackframe does not have a location, it returns an empty location', () => {
343409
// Prepare
344410
const formatter = new PowertoolsLogFormatter();
345411
const stack = 'A weird stack trace...';

0 commit comments

Comments
 (0)