fix(session): retry 5xx server errors even when isRetryable is unset (#22511)
This commit is contained in:
@@ -56,7 +56,10 @@ export namespace SessionRetry {
|
|||||||
// context overflow errors should not be retried
|
// context overflow errors should not be retried
|
||||||
if (MessageV2.ContextOverflowError.isInstance(error)) return undefined
|
if (MessageV2.ContextOverflowError.isInstance(error)) return undefined
|
||||||
if (MessageV2.APIError.isInstance(error)) {
|
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
|
if (error.data.responseBody?.includes("FreeUsageLimitError")) return GO_UPSELL_MESSAGE
|
||||||
return error.data.message.includes("Overloaded") ? "Provider is overloaded" : error.data.message
|
return error.data.message.includes("Overloaded") ? "Provider is overloaded" : error.data.message
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -178,6 +178,47 @@ describe("session.retry.retryable", () => {
|
|||||||
expect(SessionRetry.retryable(error)).toBeUndefined()
|
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", () => {
|
test("retries ZlibError decompression failures", () => {
|
||||||
const error = new MessageV2.APIError({
|
const error = new MessageV2.APIError({
|
||||||
message: "Response decompression failed",
|
message: "Response decompression failed",
|
||||||
|
|||||||
Reference in New Issue
Block a user