feat(utils): include stackTrace in serializeError

This commit is contained in:
Jiri Zbytovsky
2025-01-28 15:14:37 +01:00
committed by Jiri Zbytovsky
parent 54151a2510
commit fb496b7f19
2 changed files with 24 additions and 5 deletions

View File

@@ -2,10 +2,14 @@
* Serialize an error of unknown type to a string.
*/
export const serializeError = (error: unknown): string => {
// Error instances are objects, but have no JSON printable properties
// Error instances are objects, but have no JSON printable properties.
// Instead, .toString() is their standard string representation. Though stack trace must be included separately
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/toString
if (error instanceof Error) {
return error.toString();
return JSON.stringify({ message: error.toString(), stackTrace: error.stack });
}
// plain javascript object is not a conventional error type, but we have to count with it
if (typeof error === 'object') {
return JSON.stringify(error);
}

View File

@@ -4,17 +4,32 @@ class CustomError extends Error {
somethingExtra = 'extra stuff';
toString() {
return `${super.toString()} + ${this.somethingExtra} `;
return `${super.toString()} + ${this.somethingExtra}`;
}
}
describe(serializeError.name, () => {
it('serializes an Error instance', () => {
const error = new Error('example message');
expect(serializeError(error)).toBe('Error: example message');
/*
A very crude way to mock the stack trace.. But although we can generally mock anything in Jest,
(in this case that would be Error.prototype.captureStackTrace that sets the Error.stack property)
specifically errors are not mockable, as Jest relies on them internally and it bugs out Jest.
But couldn't we then do it at least for CustomError? No, because for Error instances,
JavaScript bypasses the prototype chain and calls Error.prototype.captureStackTrace directly.
*/
error.stack = 'Mock Stack Trace';
expect(JSON.parse(serializeError(error))).toMatchObject({
message: 'Error: example message',
stackTrace: 'Mock Stack Trace',
});
const customError = new CustomError('example message');
expect(serializeError(customError)).toBe('Error: example message + extra stuff ');
customError.stack = 'Mock Stack Trace';
expect(JSON.parse(serializeError(customError))).toMatchObject({
message: 'Error: example message + extra stuff',
stackTrace: 'Mock Stack Trace',
});
});
it('serializes a plain object', () => {