fix(model-fallback): retry forbidden provider errors
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import { describe, it, expect, afterEach, mock, spyOn } from "bun:test"
|
||||
|
||||
import { createEventHandler } from "./event"
|
||||
import { createEventHandler, extractErrorMessage } from "./event"
|
||||
import { createChatMessageHandler } from "./chat-message"
|
||||
import * as openclawRuntimeDispatch from "../openclaw/runtime-dispatch"
|
||||
import { _resetForTesting, setMainSession } from "../features/claude-code-session-state"
|
||||
@@ -93,6 +93,23 @@ afterEach(() => {
|
||||
_resetForTesting()
|
||||
})
|
||||
|
||||
describe("event error extraction", () => {
|
||||
it("prefers nested APIError message over generic top-level message", async () => {
|
||||
//#given
|
||||
const error = {
|
||||
name: "APIError",
|
||||
message: "Error",
|
||||
data: { message: "Forbidden: Selected provider is forbidden" },
|
||||
}
|
||||
|
||||
//#when
|
||||
const result = extractErrorMessage(error)
|
||||
|
||||
//#then
|
||||
expect(result).toBe("Forbidden: Selected provider is forbidden")
|
||||
})
|
||||
})
|
||||
|
||||
describe("createEventHandler - idle deduplication", () => {
|
||||
it("#given synthetic idle fires first #when real idle arrives within 500ms #then real idle dispatched", async () => {
|
||||
//#given
|
||||
|
||||
+5
-4
@@ -63,18 +63,17 @@ function extractErrorName(error: unknown): string | undefined {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function extractErrorMessage(error: unknown): string {
|
||||
export function extractErrorMessage(error: unknown): string {
|
||||
if (!error) return "";
|
||||
if (typeof error === "string") return error;
|
||||
if (error instanceof Error) return error.message;
|
||||
|
||||
if (isRecord(error)) {
|
||||
const candidates: unknown[] = [
|
||||
error,
|
||||
error.data,
|
||||
error.error,
|
||||
isRecord(error.data) ? error.data.error : undefined,
|
||||
error.error,
|
||||
error.cause,
|
||||
error,
|
||||
];
|
||||
|
||||
for (const candidate of candidates) {
|
||||
@@ -84,6 +83,8 @@ function extractErrorMessage(error: unknown): string {
|
||||
}
|
||||
}
|
||||
|
||||
if (error instanceof Error) return error.message;
|
||||
|
||||
try {
|
||||
return JSON.stringify(error);
|
||||
} catch {
|
||||
|
||||
Reference in New Issue
Block a user