@@ -83,6 +83,28 @@ function firstGuardedFetchCall(): Record<string, unknown> {
|
83 | 83 | return call as Record<string, unknown>; |
84 | 84 | } |
85 | 85 | |
| 86 | +function cancelTrackedResponse( |
| 87 | +text: string, |
| 88 | +init: ResponseInit, |
| 89 | +): { |
| 90 | +response: Response; |
| 91 | +wasCanceled: () => boolean; |
| 92 | +} { |
| 93 | +let canceled = false; |
| 94 | +const stream = new ReadableStream<Uint8Array>({ |
| 95 | +start(controller) { |
| 96 | +controller.enqueue(new TextEncoder().encode(text)); |
| 97 | +}, |
| 98 | +cancel() { |
| 99 | +canceled = true; |
| 100 | +}, |
| 101 | +}); |
| 102 | +return { |
| 103 | +response: new Response(stream, init), |
| 104 | +wasCanceled: () => canceled, |
| 105 | +}; |
| 106 | +} |
| 107 | + |
86 | 108 | function expectEmbeddingFetch( |
87 | 109 | fetchMock: ReturnType<typeof mockEmbeddingFetch>, |
88 | 110 | url: string, |
@@ -317,6 +339,39 @@ describe("ollama embedding provider", () => {
|
317 | 339 | }); |
318 | 340 | }); |
319 | 341 | |
| 342 | +it("bounds embed error bodies without using response.text()", async () => { |
| 343 | +const tracked = cancelTrackedResponse(`${"ollama embed unavailable ".repeat(1024)}tail`, { |
| 344 | +status: 503, |
| 345 | +headers: { "content-type": "text/plain" }, |
| 346 | +}); |
| 347 | +const textSpy = vi.spyOn(tracked.response, "text").mockRejectedValue(new Error("unbounded")); |
| 348 | +vi.stubGlobal( |
| 349 | +"fetch", |
| 350 | +vi.fn(async () => tracked.response), |
| 351 | +); |
| 352 | + |
| 353 | +const { provider } = await createOllamaEmbeddingProvider({ |
| 354 | +config: {} as OpenClawConfig, |
| 355 | +provider: "ollama", |
| 356 | +model: "nomic-embed-text", |
| 357 | +fallback: "none", |
| 358 | +remote: { baseUrl: "http://127.0.0.1:11434" }, |
| 359 | +}); |
| 360 | + |
| 361 | +let error: unknown; |
| 362 | +try { |
| 363 | +await provider.embedQuery("hello"); |
| 364 | +} catch (err) { |
| 365 | +error = err; |
| 366 | +} |
| 367 | + |
| 368 | +expect(String(error)).toContain("Ollama embed HTTP 503"); |
| 369 | +expect(String(error)).toContain("ollama embed unavailable"); |
| 370 | +expect(String(error)).not.toContain("tail"); |
| 371 | +expect(tracked.wasCanceled()).toBe(true); |
| 372 | +expect(textSpy).not.toHaveBeenCalled(); |
| 373 | +}); |
| 374 | + |
320 | 375 | it("reports malformed embed JSON with a provider-owned error", async () => { |
321 | 376 | vi.stubGlobal( |
322 | 377 | "fetch", |
|