( error: Error | TestResult.SerializableError | string | number | undefined, config: StackTraceConfig, options: StackTraceOptions, testPath?: string, reuseMessage?: boolean, noTitle?: boolean, )
| 123 | // `before/after each` hooks). If it's thrown, none of the tests in the file |
| 124 | // are executed. |
| 125 | export const formatExecError = ( |
| 126 | error: Error | TestResult.SerializableError | string | number | undefined, |
| 127 | config: StackTraceConfig, |
| 128 | options: StackTraceOptions, |
| 129 | testPath?: string, |
| 130 | reuseMessage?: boolean, |
| 131 | noTitle?: boolean, |
| 132 | ): string => { |
| 133 | if (!error || typeof error === 'number') { |
| 134 | error = new Error(`Expected an Error, but "${String(error)}" was thrown`); |
| 135 | error.stack = ''; |
| 136 | } |
| 137 | |
| 138 | let message, stack; |
| 139 | let cause = ''; |
| 140 | const subErrors = []; |
| 141 | |
| 142 | if (typeof error === 'string' || !error) { |
| 143 | error ||= 'EMPTY ERROR'; |
| 144 | message = ''; |
| 145 | stack = error; |
| 146 | } else { |
| 147 | message = error.message; |
| 148 | stack = |
| 149 | typeof error.stack === 'string' |
| 150 | ? error.stack |
| 151 | : `thrown: ${prettyFormat(error, {maxDepth: 3})}`; |
| 152 | if ('cause' in error) { |
| 153 | const prefix = '\n\nCause:\n'; |
| 154 | if (typeof error.cause === 'string' || typeof error.cause === 'number') { |
| 155 | cause += `${prefix}${error.cause}`; |
| 156 | } else if (isError(error.cause) || error.cause instanceof Error) { |
| 157 | /* `isError` is used, because the error might come from another realm. |
| 158 | `instanceof Error` is used because `isError` does return `false` for some |
| 159 | things that are `instanceof Error` like the errors provided in |
| 160 | [verror](https://www.npmjs.com/package/verror) or [axios](https://axios-http.com). |
| 161 | */ |
| 162 | const formatted = formatExecError( |
| 163 | error.cause, |
| 164 | config, |
| 165 | options, |
| 166 | testPath, |
| 167 | reuseMessage, |
| 168 | true, |
| 169 | ); |
| 170 | cause += `${prefix}${formatted}`; |
| 171 | } |
| 172 | } |
| 173 | if ('errors' in error && Array.isArray(error.errors)) { |
| 174 | for (const subError of error.errors) { |
| 175 | subErrors.push( |
| 176 | formatExecError( |
| 177 | subError, |
| 178 | config, |
| 179 | options, |
| 180 | testPath, |
| 181 | reuseMessage, |
| 182 | true, |
no test coverage detected