fix(session): retry 5xx server errors even when isRetryable is unset (#22511)

This commit is contained in:
Kit Langton
2026-04-15 20:58:48 -04:00
committed by GitHub
parent a147ad68e6
commit 4ca809ef4e
2 changed files with 45 additions and 1 deletions

View File

@@ -56,7 +56,10 @@ export namespace SessionRetry {
// context overflow errors should not be retried
if (MessageV2.ContextOverflowError.isInstance(error)) return undefined
if (MessageV2.APIError.isInstance(error)) {
if (!error.data.isRetryable) return undefined
const status = error.data.statusCode
// 5xx errors are transient server failures and should always be retried,
// even when the provider SDK doesn't explicitly mark them as retryable.
if (!error.data.isRetryable && !(status !== undefined && status >= 500)) return undefined
if (error.data.responseBody?.includes("FreeUsageLimitError")) return GO_UPSELL_MESSAGE
return error.data.message.includes("Overloaded") ? "Provider is overloaded" : error.data.message
}

View File

@@ -178,6 +178,47 @@ describe("session.retry.retryable", () => {
expect(SessionRetry.retryable(error)).toBeUndefined()
})
test("retries 500 errors even when isRetryable is false", () => {
const error = new MessageV2.APIError({
message: "Internal server error",
isRetryable: false,
statusCode: 500,
responseBody: '{"type":"api_error","message":"Internal server error"}',
}).toObject() as MessageV2.APIError
expect(SessionRetry.retryable(error)).toBe("Internal server error")
})
test("retries 502 bad gateway errors", () => {
const error = new MessageV2.APIError({
message: "Bad gateway",
isRetryable: false,
statusCode: 502,
}).toObject() as MessageV2.APIError
expect(SessionRetry.retryable(error)).toBe("Bad gateway")
})
test("retries 503 service unavailable errors", () => {
const error = new MessageV2.APIError({
message: "Service unavailable",
isRetryable: false,
statusCode: 503,
}).toObject() as MessageV2.APIError
expect(SessionRetry.retryable(error)).toBe("Service unavailable")
})
test("does not retry 4xx errors when isRetryable is false", () => {
const error = new MessageV2.APIError({
message: "Bad request",
isRetryable: false,
statusCode: 400,
}).toObject() as MessageV2.APIError
expect(SessionRetry.retryable(error)).toBeUndefined()
})
test("retries ZlibError decompression failures", () => {
const error = new MessageV2.APIError({
message: "Response decompression failed",