diff --git a/src/helpers/errors.js b/src/helpers/errors.js index 20cf70ec8..73ce796cf 100644 --- a/src/helpers/errors.js +++ b/src/helpers/errors.js @@ -39,6 +39,13 @@ export const createQueryByError = (error: Error, callsite: Function) => { throw new ErrorWithStack(error.message, callsite); }; +export function copyStackTrace(target: Error, stackTraceSource: Error) { + target.stack = stackTraceSource.stack.replace( + stackTraceSource.message, + target.message + ); +} + const warned = {}; export function printDeprecationWarning(functionName: string) { diff --git a/src/waitFor.js b/src/waitFor.js index 1820dbe88..45c929771 100644 --- a/src/waitFor.js +++ b/src/waitFor.js @@ -2,7 +2,11 @@ import * as React from 'react'; import act from './act'; -import { throwRemovedFunctionError } from './helpers/errors'; +import { + ErrorWithStack, + throwRemovedFunctionError, + copyStackTrace, +} from './helpers/errors'; const DEFAULT_TIMEOUT = 4500; const DEFAULT_INTERVAL = 50; @@ -26,10 +30,13 @@ function waitForInternal( const timeout = options?.timeout ?? DEFAULT_TIMEOUT; const interval = options?.interval ?? DEFAULT_INTERVAL; const startTime = Date.now(); + // Being able to display a useful stack trace requires generating it before doing anything async + const stackTraceError = new ErrorWithStack('STACK_TRACE_ERROR', waitFor); return new Promise((resolve, reject) => { const rejectOrRerun = (error) => { if (Date.now() - startTime >= timeout) { + copyStackTrace(error, stackTraceError); reject(error); return; }