Skip to content

Commit 4b80d9f

Browse files
dreamorosiam29d
andauthored
feat(logger): include enumerable properties in formatted errors (#3195)
Co-authored-by: Alexander Schueren <[email protected]>
1 parent d4a41d3 commit 4b80d9f

File tree

2 files changed

+70
-9
lines changed

2 files changed

+70
-9
lines changed

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

+12-4
Original file line numberDiff line numberDiff line change
@@ -104,16 +104,24 @@ abstract class LogFormatter {
104104
* @param error - Error to format
105105
*/
106106
public formatError(error: Error): LogAttributes {
107-
return {
108-
name: error.name,
107+
const { name, message, stack, cause, ...errorAttributes } = error;
108+
const formattedError: LogAttributes = {
109+
name,
109110
location: this.getCodeLocation(error.stack),
110-
message: error.message,
111-
stack: error.stack,
111+
message,
112+
stack,
112113
cause:
113114
error.cause instanceof Error
114115
? this.formatError(error.cause)
115116
: error.cause,
116117
};
118+
for (const key in error) {
119+
if (typeof key === 'string' && !['name', 'message', 'stack', 'cause'].includes(key)) {
120+
formattedError[key] = (errorAttributes as Record<string, unknown>)[key];
121+
}
122+
}
123+
124+
return formattedError;
117125
}
118126

119127
/**

Diff for: packages/logger/tests/unit/formatters.test.ts

+58-5
Original file line numberDiff line numberDiff line change
@@ -357,7 +357,6 @@ describe('Formatters', () => {
357357
},
358358
{
359359
error: new AssertionError({
360-
message: 'Expected values to be strictly equal',
361360
actual: 1,
362361
expected: 2,
363362
operator: 'strictEqual',
@@ -369,6 +368,11 @@ describe('Formatters', () => {
369368
),
370369
message: expect.stringMatching(/Expected values to be strictly equal/),
371370
cause: undefined,
371+
actual: 1,
372+
expected: 2,
373+
operator: 'strictEqual',
374+
code: 'ERR_ASSERTION',
375+
generatedMessage: true,
372376
},
373377
},
374378
{
@@ -432,16 +436,65 @@ describe('Formatters', () => {
432436
cause: 'bar',
433437
},
434438
},
435-
])('formats errors correctly ($name)', ({ error, name, expectedFields }) => {
439+
])(
440+
'formats standard errors correctly ($name)',
441+
({ error, name, expectedFields }) => {
442+
// Act
443+
const formattedError = formatter.formatError(error);
444+
445+
// Assess
446+
expect(formattedError).toEqual({
447+
location: expect.stringMatching(fileNameRegexp),
448+
stack: expect.stringMatching(fileNameRegexpWithLine),
449+
name,
450+
...expectedFields,
451+
});
452+
}
453+
);
454+
455+
it('formats custom errors by including only enumerable properties', () => {
456+
// Prepare
457+
const customSymbol = Symbol('customSymbol');
458+
class CustomError extends Error {
459+
public otherProperty: string;
460+
461+
public constructor(
462+
message: string,
463+
public readonly code: number
464+
) {
465+
super(message);
466+
this.name = 'CustomError';
467+
this.otherProperty = 'otherProperty';
468+
}
469+
470+
public [customSymbol] = (): void => {
471+
// do nothing
472+
};
473+
}
474+
475+
class SuperCustomError extends CustomError {
476+
public extraProperty: string;
477+
public constructor(message: string, code: number) {
478+
super(message, code);
479+
this.name = 'SuperCustomError';
480+
this.extraProperty = 'extraProperty';
481+
}
482+
}
483+
436484
// Act
437-
const formattedError = formatter.formatError(error);
485+
const formattedError = formatter.formatError(
486+
new SuperCustomError('Something went wrong', 500)
487+
);
438488

439489
// Assess
440490
expect(formattedError).toEqual({
441491
location: expect.stringMatching(fileNameRegexp),
442492
stack: expect.stringMatching(fileNameRegexpWithLine),
443-
name,
444-
...expectedFields,
493+
name: 'SuperCustomError',
494+
message: 'Something went wrong',
495+
code: 500,
496+
otherProperty: 'otherProperty',
497+
extraProperty: 'extraProperty',
445498
});
446499
});
447500

0 commit comments

Comments
 (0)