Skip to content

Commit

Permalink
feat(jest-message-util): add support for error causes
Browse files Browse the repository at this point in the history
  • Loading branch information
brodo committed Feb 7, 2023
1 parent 5a9870b commit 8791e02
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 3 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -3,6 +3,7 @@
### Features

- `[@jest/core]` Instrument significant lifecycle events with [`performance.mark()`](https://nodejs.org/docs/latest-v16.x/api/perf_hooks.html#performancemarkname-options) ([#13859](https://github.com/facebook/jest/pull/13859))
- `[jest-message-util]` Add support for [error causes](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/cause)

### Fixes

Expand Down
17 changes: 17 additions & 0 deletions packages/jest-message-util/src/__tests__/messages.test.ts
Expand Up @@ -413,3 +413,20 @@ it('getTopFrame should return a path for mjs files', () => {

expect(frame!.file).toBe(expectedFile);
});

it('should return the error cause if there is one', () => {
const error = new Error('Test exception');
// We need to do it this way because in older Javascript engines the constructor does not allow supplying a cause.
error.cause = new Error('Cause Error');
const message = formatExecError(
error,
{
rootDir: '',
testMatch: [],
},
{
noStackTrace: false,
},
);
expect(message).toEqual(expect.stringContaining('Cause'));
});
30 changes: 27 additions & 3 deletions packages/jest-message-util/src/index.ts
Expand Up @@ -122,18 +122,20 @@ function warnAboutWrongTestEnvironment(error: string, env: 'jsdom' | 'node') {
// `before/after each` hooks). If it's thrown, none of the tests in the file
// are executed.
export const formatExecError = (
error: Error | TestResult.SerializableError | string | undefined,
error: Error | TestResult.SerializableError | string | undefined | number,
config: StackTraceConfig,
options: StackTraceOptions,
testPath?: string,
reuseMessage?: boolean,
noTitle?: boolean,
): string => {
if (!error || typeof error === 'number') {
error = new Error(`Expected an Error, but "${String(error)}" was thrown`);
error.stack = '';
}

let message, stack;
let cause = '';

if (typeof error === 'string' || !error) {
error || (error = 'EMPTY ERROR');
Expand All @@ -145,6 +147,27 @@ export const formatExecError = (
typeof error.stack === 'string'
? error.stack
: `thrown: ${prettyFormat(error, {maxDepth: 3})}`;
if ('cause' in error) {
const prefix = '\n\nCause:\n';
if (typeof error.cause === 'string') {
cause += `${prefix}${error.cause}`;
} else if (typeof error.cause === 'number') {
cause += `${prefix}${error.cause.toString()}`;
} else if (error.cause instanceof Error) {
const formatted = formatExecError(
error.cause,
config,
options,
testPath,
reuseMessage,
true,
);
cause += `${prefix}${formatted}`;
}
}
}
if (cause !== '') {
cause = indentAllLines(cause);
}

const separated = separateMessageFromStack(stack || '');
Expand Down Expand Up @@ -174,13 +197,14 @@ export const formatExecError = (

let messageToUse;

if (reuseMessage) {
if (reuseMessage || noTitle) {
messageToUse = ` ${message.trim()}`;
} else {
messageToUse = `${EXEC_ERROR_MESSAGE}\n\n${message}`;
}
const title = noTitle ? '' : `${TITLE_INDENT + TITLE_BULLET}`;

return `${TITLE_INDENT + TITLE_BULLET + messageToUse + stack}\n`;
return `${title + messageToUse + stack + cause}\n`;
};

const removeInternalStackEntries = (
Expand Down

0 comments on commit 8791e02

Please sign in to comment.