Skip to content

Commit a7290a3

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

File tree

2 files changed

+68
-4
lines changed

2 files changed

+68
-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

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

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

0 commit comments

Comments
 (0)