fix: tighten 402 failover classification

This commit is contained in:
Altay
2026-04-16 19:17:58 +03:00
parent e2e494e4ae
commit 3c9587740f
2 changed files with 12 additions and 14 deletions

View File

@@ -923,6 +923,9 @@ describe("classifyFailoverReasonFromHttpStatus 402 temporary limits", () =>
expect(classifyFailoverReasonFromHttpStatus(402, undefined)).toBe("billing");
expect(classifyFailoverReasonFromHttpStatus(402, "")).toBe("billing");
expect(classifyFailoverReasonFromHttpStatus(402, "Payment required")).toBe("billing");
expect(classifyFailoverReasonFromHttpStatus(402, "402 custom proxy billing failure")).toBe(
"billing",
);
});
it("matches raw 402 wrappers and status-split payloads for the same message", () => {

View File

@@ -583,7 +583,7 @@ export function classifyFailoverReasonFromHttpStatus(
? classifyFailoverClassificationFromMessage(message, opts?.provider)
: null;
return failoverReasonFromClassification(
classifyFailoverClassificationFromHttpStatus(status, message, messageClassification),
classifyFailoverClassificationFromHttpStatus(status, message, messageClassification, status),
);
}
@@ -591,6 +591,7 @@ function classifyFailoverClassificationFromHttpStatus(
status: number | undefined,
message: string | undefined,
messageClassification: FailoverClassification | null,
explicitStatus: number | undefined,
): FailoverClassification | null {
const messageReason = failoverReasonFromClassification(messageClassification);
if (typeof status !== "number" || !Number.isFinite(status)) {
@@ -604,7 +605,12 @@ function classifyFailoverClassificationFromHttpStatus(
const leadingStatus = extractLeadingHttpStatus(message.trim());
if (leadingStatus?.code === 402) {
const reasonFrom402Text = classifyFailoverReasonFrom402Text(message);
return reasonFrom402Text ? toReasonClassification(reasonFrom402Text) : messageClassification;
if (reasonFrom402Text) {
return toReasonClassification(reasonFrom402Text);
}
return typeof explicitStatus === "number"
? toReasonClassification("billing")
: messageClassification;
}
return toReasonClassification(classify402Message(message));
}
@@ -835,6 +841,7 @@ export function classifyFailoverSignal(signal: FailoverSignal): FailoverClassifi
inferredStatus,
signal.message,
messageClassification,
signal.status,
);
if (statusClassification) {
return statusClassification;
@@ -1246,20 +1253,8 @@ export function classifyFailoverReason(
raw: string,
opts?: { provider?: string },
): FailoverReason | null {
const trimmed = raw.trim();
const leadingStatus = extractLeadingHttpStatus(trimmed);
const reasonFrom402Text =
leadingStatus?.code === 402 ? classifyFailoverReasonFrom402Text(trimmed) : null;
if (
leadingStatus?.code === 402 &&
!reasonFrom402Text &&
!isHtmlErrorResponse(trimmed, leadingStatus.code)
) {
return null;
}
return failoverReasonFromClassification(
classifyFailoverSignal({
status: leadingStatus?.code,
message: raw,
provider: opts?.provider,
}),