diff --git a/packages/ai-ollama/src/adapters/text.ts b/packages/ai-ollama/src/adapters/text.ts index d082db0af..b7ae351f2 100644 --- a/packages/ai-ollama/src/adapters/text.ts +++ b/packages/ai-ollama/src/adapters/text.ts @@ -1,4 +1,8 @@ import { EventType, normalizeSystemPrompts } from '@tanstack/ai' +import { + toRunErrorPayload, + toRunErrorRawEvent, +} from '@tanstack/ai/adapter-internals' import { BaseTextAdapter } from '@tanstack/ai/adapters' import { buildOllamaUsage } from '../usage' import { createOllamaClient, generateId, getOllamaHostFromEnv } from '../utils' @@ -112,11 +116,27 @@ export class OllamaTextAdapter extends BaseTextAdapter< }) yield* this.processOllamaStreamChunks(response, options, logger) } catch (error: unknown) { + const errorPayload = toRunErrorPayload( + error, + 'An unknown error occurred during the chat stream.', + ) + const rawEvent = toRunErrorRawEvent(error) logger.errors('ollama.chatStream fatal', { error, source: 'ollama.chatStream', }) - throw error + yield { + type: EventType.RUN_ERROR, + model: options.model, + timestamp: Date.now(), + message: errorPayload.message, + code: errorPayload.code, + ...(rawEvent !== undefined && { rawEvent }), + error: { + message: errorPayload.message, + code: errorPayload.code, + }, + } } } diff --git a/packages/ai-ollama/tests/text-adapter.test.ts b/packages/ai-ollama/tests/text-adapter.test.ts index f5836bd70..d8ae8beb9 100644 --- a/packages/ai-ollama/tests/text-adapter.test.ts +++ b/packages/ai-ollama/tests/text-adapter.test.ts @@ -590,3 +590,24 @@ describe('OllamaTextAdapter system prompts', () => { expect(roles).not.toContain('system') }) }) + +describe('Ollama adapter error handling', () => { + it('emits RUN_ERROR on pre-stream client.chat rejection without throwing', async () => { + chatMock.mockRejectedValueOnce(new Error('connection refused')) + const adapter = createOllamaChat('llama3.2') + const chunks = await collectStream( + adapter.chatStream({ + logger: testLogger, + model: 'llama3.2', + messages: [{ role: 'user', content: 'hi' }], + }), + ) + + expect(chunks).toHaveLength(1) + expect(chunks[0]?.type).toBe('RUN_ERROR') + if (chunks[0]?.type === 'RUN_ERROR') { + expect(chunks[0].message).toBe('connection refused') + expect(chunks[0].error?.message).toBe('connection refused') + } + }) +})