(run, label, options = {})
| 806 | } |
| 807 | |
| 808 | async function retryAsync(run, label, options = {}) { |
| 809 | const attempts = options.attempts ?? 3; |
| 810 | const delayMs = options.delayMs ?? 1_000; |
| 811 | let lastError = null; |
| 812 | for (let attempt = 1; attempt <= attempts; attempt += 1) { |
| 813 | try { |
| 814 | return await run(); |
| 815 | } catch (error) { |
| 816 | lastError = error; |
| 817 | if (attempt < attempts) { |
| 818 | if (verbose) { |
| 819 | console.log( |
| 820 | `${label} attempt ${attempt}/${attempts} failed: ${error.message}`, |
| 821 | ); |
| 822 | } |
| 823 | await sleep(delayMs); |
| 824 | } |
| 825 | } |
| 826 | } |
| 827 | throw lastError; |
| 828 | } |
| 829 | |
| 830 | function printTimingSummary() { |
| 831 | if (!verbose || stepTimings.length === 0) { |
no test coverage detected