{"record":{"id":"0d18a0250ad9e0af","repo":"linshenkx/prompt-optimizer","slug":"context-lasterror-as-error-message-str","errorCode":null,"errorMessage":"${context}: ${(lastError as Error)?.message || String(lastError)}","messagePattern":"\\$\\{context\\}: \\$\\{\\(lastError as Error\\)\\?\\.message \\|\\| String\\(lastError\\)\\}","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/ui/src/utils/remote-backup.ts","lineNumber":583,"sourceCode":"      if (response.ok) return response\n      if (options?.returnAuthFailures && isGoogleAuthStatus(response.status)) {\n        return response\n      }\n      if (!isRetryableHttpStatus(response.status) || attempt === GOOGLE_DRIVE_DOWNLOAD_RETRY_ATTEMPTS) {\n        return assertOkResponse(response, context)\n      }\n      lastError = new Error(`${context}: ${response.status} ${response.statusText}`)\n    } catch (error) {\n      if (!isRetryableFetchError(error) || attempt === GOOGLE_DRIVE_DOWNLOAD_RETRY_ATTEMPTS) {\n        throw new Error(`${context}: ${(error as Error).message || String(error)}`, { cause: error })\n      }\n      lastError = error\n    }\n\n    await sleep(GOOGLE_DRIVE_DOWNLOAD_RETRY_BASE_DELAY_MS * attempt)\n  }\n\n  throw new Error(`${context}: ${(lastError as Error)?.message || String(lastError)}`)\n}\n\nexport const joinRemotePath = (...parts: string[]): string =>\n  parts\n    .map((part) => part.replace(/^\\/+|\\/+$/g, ''))\n    .filter(Boolean)\n    .join('/')\n\nconst normalizeObjectPath = (path: string): string => joinRemotePath(path)\n\nconst parentPathOf = (path: string): string => {\n  const normalized = normalizeObjectPath(path)\n  const index = normalized.lastIndexOf('/')\n  return index === -1 ? '' : normalized.slice(0, index)\n}\n\nconst fileNameOf = (path: string): string => normalizeObjectPath(path).split('/').pop() || ''\n","sourceCodeStart":565,"sourceCodeEnd":601,"githubUrl":"https://github.com/linshenkx/prompt-optimizer/blob/3e677b1d9f7e0493c142c175560531e7ae786dce/packages/ui/src/utils/remote-backup.ts#L565-L601","documentation":"Thrown at the end of the Google Drive download retry loop when the loop exits without a successful response or a thrown terminal error. The last recorded error (either an HTTP-status error or a network error from earlier attempts) is re-wrapped with the operation context and thrown, guaranteeing the caller always gets an Error when all attempts fail.","triggerScenarios":"Every retry attempt got a retryable HTTP status (e.g. repeated 500/503) until the budget ran out; or the loop completed with lastError set from a prior catch and fell through to this final throw. Functionally the 'retries exhausted with retryable HTTP failures' counterpart of error 576.","commonSituations":"Google Drive/S3 returning sustained 500/503 during an outage; repeated 429 rate-limiting because the backoff is too short; throttled service accounts hammering the API.","solutions":["Treat sustained retryable statuses as a provider outage: wait and retry the whole download later","Reduce concurrent backup operations to avoid rate limiting (429)","Check the provider status page for ongoing incidents","Increase backoff base delay or attempt count if the default budget is too small for your environment"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"const attemptWithBackoff = async (fn: () => Promise<ArrayBuffer>, tries = 5) => {\n  for (let i = 0; i < tries; i++) {\n    try { return await fn() } catch (e) { if (i === tries - 1) throw e }\n    await new Promise((r) => setTimeout(r, 2 ** i * 1000))\n  }\n  throw new Error('unreachable')\n}","preventionTips":["Wrap the whole download in an outer retry with longer backoff than the inner loop","Check provider status dashboards before scheduling large restores","Throttle concurrent downloads to avoid triggering sustained 429/503"],"tags":["retry-exhausted","remote-backup","http-status","resilience"],"backgroundTag":"retry-budget-exhausted","analyzedSha":"3e677b1d9f7e0493c142c175560531e7ae786dce","analyzedAt":"2026-08-27T21:29:16.709Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}