| 448 | } |
| 449 | |
| 450 | class ConfigurationLoadingError extends Error { |
| 451 | name = "ConfigurationLoadingError"; |
| 452 | |
| 453 | constructor(errors: [unknown, unknown]) { |
| 454 | const message = |
| 455 | `▶ ESM (\`import\`) failed:\n${ConfigurationLoadingError.format(errors[0])}\n\n▶ CJS (\`require\`) failed:\n${ConfigurationLoadingError.format(errors[1])}`.trim(); |
| 456 | |
| 457 | super(message); |
| 458 | |
| 459 | this.stack = ""; |
| 460 | } |
| 461 | |
| 462 | // Format a single underlying loading error as verbosely as possible. For |
| 463 | // module-loading errors (e.g. a `SyntaxError`) `error.stack` begins with a |
| 464 | // code frame (file, line, source and a caret) that points at the exact |
| 465 | // location of the problem — far more useful than `error.message` alone. We |
| 466 | // keep the full stack and surface the Node.js error `code` (e.g. |
| 467 | // `MODULE_NOT_FOUND`) when present. |
| 468 | static format(error: unknown): string { |
| 469 | return ConfigurationLoadingError.indent(ConfigurationLoadingError.describe(error)); |
| 470 | } |
| 471 | |
| 472 | // Build the full, un-indented description of an error, walking the `cause` |
| 473 | // chain. ES2022 error causes aren't reflected in `error.stack`, so they'd |
| 474 | // otherwise be lost. A `seen` set guards against cyclic causes. |
| 475 | static describe(error: unknown, seen = new Set<unknown>()): string { |
| 476 | if (!(error instanceof Error)) { |
| 477 | return util.stripVTControlCharacters(String(error)); |
| 478 | } |
| 479 | |
| 480 | seen.add(error); |
| 481 | |
| 482 | let details = (error.stack ?? `${error.name}: ${error.message}`).trimEnd(); |
| 483 | |
| 484 | const { code } = error as NodeJS.ErrnoException; |
| 485 | |
| 486 | if (code) { |
| 487 | details += `\ncode: ${code}`; |
| 488 | } |
| 489 | |
| 490 | details = util.stripVTControlCharacters(details); |
| 491 | |
| 492 | const { cause } = error; |
| 493 | |
| 494 | if (cause !== null && cause !== undefined && !seen.has(cause)) { |
| 495 | details += `\n\nCaused by: ${ConfigurationLoadingError.describe(cause, seen)}`; |
| 496 | } |
| 497 | |
| 498 | return details; |
| 499 | } |
| 500 | |
| 501 | static indent(text: string): string { |
| 502 | return text |
| 503 | .split("\n") |
| 504 | .map((line) => (line ? ` ${line}` : line)) |
| 505 | .join("\n"); |
| 506 | } |
| 507 | } |
nothing calls this directly
no outgoing calls
no test coverage detected