fix(fallback): handle timeout aborts

Co-authored-by: Mykyta Bozhenko <21245729+cheeeee@users.noreply.github.com>
This commit is contained in:
Peter Steinberger
2026-01-18 07:52:19 +00:00
parent 3b24fe639a
commit ec27c813cc
5 changed files with 129 additions and 12 deletions

View File

@@ -1,6 +1,11 @@
import type { ClawdbotConfig } from "../config/config.js";
import { DEFAULT_MODEL, DEFAULT_PROVIDER } from "./defaults.js";
import { coerceToFailoverError, describeFailoverError, isFailoverError } from "./failover-error.js";
import {
coerceToFailoverError,
describeFailoverError,
isFailoverError,
isTimeoutError,
} from "./failover-error.js";
import {
buildModelAliasIndex,
modelKey,
@@ -26,6 +31,7 @@ type FallbackAttempt = {
function isAbortError(err: unknown): boolean {
if (!err || typeof err !== "object") return false;
if (isFailoverError(err)) return false;
const name = "name" in err ? String(err.name) : "";
if (name === "AbortError") return true;
const message =
@@ -33,6 +39,10 @@ function isAbortError(err: unknown): boolean {
return message.includes("aborted");
}
function shouldRethrowAbort(err: unknown): boolean {
return isAbortError(err) && !isTimeoutError(err);
}
function buildAllowedModelKeys(
cfg: ClawdbotConfig | undefined,
defaultProvider: string,
@@ -216,7 +226,7 @@ export async function runWithModelFallback<T>(params: {
attempts,
};
} catch (err) {
if (isAbortError(err)) throw err;
if (shouldRethrowAbort(err)) throw err;
const normalized =
coerceToFailoverError(err, {
provider: candidate.provider,
@@ -303,7 +313,7 @@ export async function runWithImageModelFallback<T>(params: {
attempts,
};
} catch (err) {
if (isAbortError(err)) throw err;
if (shouldRethrowAbort(err)) throw err;
lastError = err;
attempts.push({
provider: candidate.provider,