import {colorText} from '../colorText'; export class TimeoutError extends Error { constructor(params: { awaiterName: string; fn: () => unknown; cause: Error; timeout: number; message?: string; id?: string; }) { const {awaiterName, message, fn, cause, timeout, id} = params; const timeoutError: Error = Object.create( Object.getPrototypeOf(cause) as Error, Object.getOwnPropertyDescriptors(cause), ) as Error; // 10000 => 10_000, 1000000 => 1_000_000 const formattedTimeout = timeout .toString() .split('') .reverse() .reduce((acc, current, index) => { const shouldAddUnderscore = index % 3 === 0 && index !== 0; return current + (shouldAddUnderscore ? '_' : '') + acc; }, ''); if (message) { timeoutError.message = message; } const messageSection = colorText.red(awaiterName + (id ? ` [id=${id}]` : '') + ` [timeout=${formattedTimeout}]`); const functionBody = fn .toString() .replace('/* istanbul ignore next */', '') .replace(/(\/\* eslint-disable-next-line.*\*\/)/, '\n$1') .replace(/cov_.*;/gi, '') .replace(/\s{2,}/g, '\n') .split('\n') .map((line, i, lines) => (i !== 0 && i !== lines.length - 1 ? ` ${line}` : line)) .join('\n'); const functionBodySection = `\n${colorText.yellow('Function')}\n${functionBody}`; const errorsSection = `\n${colorText.yellow('Error')}\n${timeoutError}`; super(messageSection + functionBodySection + errorsSection); this.cause = cause; } }