From f16d55ad9503a322c096289f8d8089e6854100d0 Mon Sep 17 00:00:00 2001 From: MoerAI Date: Mon, 23 Mar 2026 15:19:09 +0900 Subject: [PATCH] fix: add errorName-based quota detection and strengthen test coverage --- .../runtime-fallback/error-classifier.test.ts | 24 +++++++++++++++++++ .../runtime-fallback/error-classifier.ts | 3 +++ 2 files changed, 27 insertions(+) diff --git a/src/hooks/runtime-fallback/error-classifier.test.ts b/src/hooks/runtime-fallback/error-classifier.test.ts index 20f1c0c7e..ba9b70f1a 100644 --- a/src/hooks/runtime-fallback/error-classifier.test.ts +++ b/src/hooks/runtime-fallback/error-classifier.test.ts @@ -238,4 +238,28 @@ describe("quota error detection (fixes #2747)", () => { //#then expect(retryable).toBe(true) }) + + test("classifies QuotaExceededError by errorName even without quota keywords in message", () => { + //#given + const error = { name: "QuotaExceededError", message: "Request failed." } + + //#when + const errorType = classifyErrorType(error) + + //#then + expect(errorType).toBe("quota_exceeded") + }) + + test("matches payment required pattern directly via RETRYABLE_ERROR_PATTERNS", () => { + //#given — message has no quota keyword, only "payment required" + const error = { message: "Error 402: payment required for this request" } + + //#when — classifyErrorType will NOT match (no quota keyword), so isRetryableError must use RETRYABLE_ERROR_PATTERNS + const errorType = classifyErrorType(error) + const retryable = isRetryableError(error, [429, 503]) + + //#then + expect(errorType).toBe("quota_exceeded") + expect(retryable).toBe(true) + }) }) diff --git a/src/hooks/runtime-fallback/error-classifier.ts b/src/hooks/runtime-fallback/error-classifier.ts index 12c70432e..088735edd 100644 --- a/src/hooks/runtime-fallback/error-classifier.ts +++ b/src/hooks/runtime-fallback/error-classifier.ts @@ -120,6 +120,9 @@ export function classifyErrorType(error: unknown): string | undefined { } if ( + errorName?.includes("quotaexceeded") || + errorName?.includes("insufficientquota") || + errorName?.includes("billingerror") || /quota.?exceeded/i.test(message) || /subscription.*quota/i.test(message) || /insufficient.?quota/i.test(message) ||