Merge fce6e08594 into 09be5d45d5
This commit is contained in:
commit
8c1882b0f6
@ -282,17 +282,23 @@ export async function fetchFirecrawlContent(params: {
|
|||||||
storeInCache: params.storeInCache,
|
storeInCache: params.storeInCache,
|
||||||
};
|
};
|
||||||
|
|
||||||
const res = await fetch(endpoint, {
|
let res: Response;
|
||||||
method: "POST",
|
try {
|
||||||
headers: {
|
res = await fetch(endpoint, {
|
||||||
Authorization: `Bearer ${params.apiKey}`,
|
method: "POST",
|
||||||
"Content-Type": "application/json",
|
headers: {
|
||||||
},
|
Authorization: `Bearer ${params.apiKey}`,
|
||||||
body: JSON.stringify(body),
|
"Content-Type": "application/json",
|
||||||
signal: withTimeout(undefined, params.timeoutSeconds * 1000),
|
},
|
||||||
});
|
body: JSON.stringify(body),
|
||||||
|
signal: withTimeout(undefined, params.timeoutSeconds * 1000),
|
||||||
|
});
|
||||||
|
} catch (err) {
|
||||||
|
const message = err instanceof Error ? err.message : String(err);
|
||||||
|
throw new Error(`Firecrawl fetch failed (network error): ${message}`);
|
||||||
|
}
|
||||||
|
|
||||||
const payload = (await res.json()) as {
|
let payload: {
|
||||||
success?: boolean;
|
success?: boolean;
|
||||||
data?: {
|
data?: {
|
||||||
markdown?: string;
|
markdown?: string;
|
||||||
@ -306,6 +312,12 @@ export async function fetchFirecrawlContent(params: {
|
|||||||
warning?: string;
|
warning?: string;
|
||||||
error?: string;
|
error?: string;
|
||||||
};
|
};
|
||||||
|
try {
|
||||||
|
payload = (await res.json()) as typeof payload;
|
||||||
|
} catch (err) {
|
||||||
|
const message = err instanceof Error ? err.message : String(err);
|
||||||
|
throw new Error(`Firecrawl fetch failed (invalid response): ${message}`);
|
||||||
|
}
|
||||||
|
|
||||||
if (!res.ok || payload?.success === false) {
|
if (!res.ok || payload?.success === false) {
|
||||||
const detail = payload?.error || res.statusText;
|
const detail = payload?.error || res.statusText;
|
||||||
|
|||||||
@ -269,4 +269,75 @@ describe("web_fetch extraction fallbacks", () => {
|
|||||||
/Web fetch failed \(500\):.*Oops/,
|
/Web fetch failed \(500\):.*Oops/,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("handles network-level fetch failure in firecrawl fallback", async () => {
|
||||||
|
const mockFetch = vi.fn((input: RequestInfo) => {
|
||||||
|
const url = requestUrl(input);
|
||||||
|
if (url.includes("api.firecrawl.dev")) {
|
||||||
|
return Promise.reject(new TypeError("fetch failed"));
|
||||||
|
}
|
||||||
|
// Direct fetch fails with 403
|
||||||
|
return Promise.resolve({
|
||||||
|
ok: false,
|
||||||
|
status: 403,
|
||||||
|
headers: makeHeaders({ "content-type": "text/html" }),
|
||||||
|
text: async () => "blocked",
|
||||||
|
} as Response);
|
||||||
|
});
|
||||||
|
// @ts-expect-error mock fetch
|
||||||
|
global.fetch = mockFetch;
|
||||||
|
|
||||||
|
const tool = createWebFetchTool({
|
||||||
|
config: {
|
||||||
|
tools: {
|
||||||
|
web: {
|
||||||
|
fetch: { cacheTtlMinutes: 0, firecrawl: { apiKey: "firecrawl-test" } },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
sandboxed: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
await expect(
|
||||||
|
tool?.execute?.("call", { url: "https://example.com/network-error" }),
|
||||||
|
).rejects.toThrow(/Firecrawl fetch failed \(network error\)/);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("handles invalid JSON response from firecrawl", async () => {
|
||||||
|
const mockFetch = vi.fn((input: RequestInfo) => {
|
||||||
|
const url = requestUrl(input);
|
||||||
|
if (url.includes("api.firecrawl.dev")) {
|
||||||
|
return Promise.resolve({
|
||||||
|
ok: true,
|
||||||
|
status: 200,
|
||||||
|
json: async () => {
|
||||||
|
throw new SyntaxError("Unexpected token");
|
||||||
|
},
|
||||||
|
} as Response);
|
||||||
|
}
|
||||||
|
return Promise.resolve({
|
||||||
|
ok: false,
|
||||||
|
status: 403,
|
||||||
|
headers: makeHeaders({ "content-type": "text/html" }),
|
||||||
|
text: async () => "blocked",
|
||||||
|
} as Response);
|
||||||
|
});
|
||||||
|
// @ts-expect-error mock fetch
|
||||||
|
global.fetch = mockFetch;
|
||||||
|
|
||||||
|
const tool = createWebFetchTool({
|
||||||
|
config: {
|
||||||
|
tools: {
|
||||||
|
web: {
|
||||||
|
fetch: { cacheTtlMinutes: 0, firecrawl: { apiKey: "firecrawl-test" } },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
sandboxed: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
await expect(
|
||||||
|
tool?.execute?.("call", { url: "https://example.com/invalid-json" }),
|
||||||
|
).rejects.toThrow(/Firecrawl fetch failed \(invalid response\)/);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user