* Log a retry attempt to the JSONL log file, capturing any rate-limit headers * present in the error response so that retry storms can be correlated with * quota exhaustion in post-run analysis. * * Call this from withRetry immediately before sleeping on a retry attempt. * * @param {an
(error, operation, attempt, delayMs)
| 188 | * @param {number} delayMs - How long the caller will sleep before the next try |
| 189 | */ |
| 190 | function logRetryEvent(error, operation, attempt, delayMs) { |
| 191 | const headers = error?.response?.headers ?? error?.headers ?? {}; |
| 192 | const status = error?.response?.status ?? error?.status ?? null; |
| 193 | |
| 194 | /** @type {Record<string, unknown>} */ |
| 195 | const entry = { |
| 196 | timestamp: new Date().toISOString(), |
| 197 | source: "retry", |
| 198 | operation, |
| 199 | attempt, |
| 200 | delay_ms: delayMs, |
| 201 | }; |
| 202 | |
| 203 | if (status != null) entry.status = status; |
| 204 | |
| 205 | const remaining = headers["x-ratelimit-remaining"]; |
| 206 | const limit = headers["x-ratelimit-limit"]; |
| 207 | const reset = headers["x-ratelimit-reset"]; |
| 208 | const resource = headers["x-ratelimit-resource"]; |
| 209 | |
| 210 | if (remaining !== undefined) entry.remaining = parseInt(remaining, 10); |
| 211 | if (limit !== undefined) entry.limit = parseInt(limit, 10); |
| 212 | if (reset) entry.reset = parseResetTimestamp(reset); |
| 213 | if (resource) entry.resource = resource; |
| 214 | |
| 215 | appendEntry(entry); |
| 216 | } |
| 217 | |
| 218 | /** |
| 219 | * Wrap a github object (as provided by actions/github-script) so that every |
no test coverage detected