{"record":{"id":"c02600ad74a46478","repo":"PaddlePaddle/PaddleOCR","slug":"service-unavailable-text","errorCode":null,"errorMessage":"Service unavailable: ${text}","messagePattern":"Service unavailable: (.+?)","errorType":"exception","errorClass":"ServiceUnavailableError","httpStatus":503,"severity":"warning","filePath":"api_sdk/typescript/src/internal/http.ts","lineNumber":243,"sourceCode":"    }\n\n    if (resp.ok) return resp;\n\n    let text = await resp.text();\n    try {\n      const payload = JSON.parse(text) as { msg?: string; message?: string; errorMsg?: string };\n      text = payload.msg || payload.message || payload.errorMsg || text;\n    } catch {\n      // Keep raw response text.\n    }\n    if (resp.status === 401 || resp.status === 403) {\n      throw new AuthError(`Authentication failed: ${text}`);\n    } else if (resp.status === 400) {\n      throw new InvalidRequestError(`Bad request: ${text}`);\n    } else if (resp.status === 429) {\n      throw new RateLimitError(`Rate limit exceeded: ${text}`);\n    } else if (resp.status === 503 || resp.status === 504) {\n      throw new ServiceUnavailableError(resp.status, `Service unavailable: ${text}`);\n    } else {\n      throw new APIError(resp.status, text);\n    }\n  }\n}\n\nfunction requireJobId(data: SubmitResponse): string {\n  if (!data || typeof data.jobId !== \"string\" || data.jobId.length === 0) {\n    throw new ResponseFormatError(\"Submit response is missing jobId.\");\n  }\n  return data.jobId;\n}\n","sourceCodeStart":225,"sourceCodeEnd":256,"githubUrl":"https://github.com/PaddlePaddle/PaddleOCR/blob/2661c7c0ef5c613e8f93c6e93b2e052399f0f854/api_sdk/typescript/src/internal/http.ts#L225-L256","documentation":"ServiceUnavailableError (extends APIError, statusCode 503 or 504) is thrown when the API or an upstream gateway answers 503 (overloaded/maintenance) or 504 (gateway timeout). The server's explanation text is embedded in the message. These are transient server-side conditions; the request itself was valid.","triggerScenarios":"Any HTTP call during backend overload, rolling maintenance windows, or when an upstream service behind the API gateway exceeds its own timeout (504). Typically appears across many requests at once rather than isolated to one call.","commonSituations":"Peak-hour capacity crunches; regional outages; deployment windows; large batch workloads stressing the service; gateway timeouts on unusually heavy documents.","solutions":["Retry with exponential backoff and jitter — 503/504 usually clear on their own within seconds to minutes","Reduce batch size or submission concurrency to lower backend pressure","Check the service status page / announcement channels for ongoing incidents","Circuit-break: if >50% of retries still fail, pause the pipeline for a cooldown instead of hammering the API"],"exampleFix":"async function resilientSubmit(fn: () => Promise<T>, tries = 5): Promise<T> {\n  for (let i = 0; ; i++) {\n    try { return await fn(); }\n    catch (e) {\n      if (e instanceof ServiceUnavailableError && i < tries - 1) {\n        await sleep(2 ** i * 1000 + Math.random() * 500);\n        continue;\n      }\n      throw e;\n    }\n  }\n}","handlingStrategy":"retry","validationCode":null,"typeGuard":"function isServiceUnavailable(e: unknown): e is ServiceUnavailableError {\n  return e instanceof ServiceUnavailableError;\n}","tryCatchPattern":"try {\n  await client.submitJson(model, payload);\n} catch (e) {\n  if (e instanceof ServiceUnavailableError) {\n    await backoff(3, () => client.submitJson(model, payload));\n  } else {\n    throw e;\n  }\n}","preventionTips":["Wrap all API calls in exponential-backoff-with-jitter retries for 503/504","Add a circuit breaker so sustained outages pause the pipeline instead of amplifying load","Check service status feeds during scheduled maintenance windows before deploying batch jobs"],"tags":["availability","retry","http","typescript"],"backgroundTag":null,"analyzedSha":"2661c7c0ef5c613e8f93c6e93b2e052399f0f854","analyzedAt":"2026-08-14T20:17:30.180Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}