From 138890b9d215bc435b894fd0808ea0568212c5fa Mon Sep 17 00:00:00 2001 From: Florian Egger Date: Tue, 19 May 2026 21:13:08 +0200 Subject: [PATCH] feat: improve UX for Ollama 404 errors (missing model) - src/ollama-client.ts: Detect HTTP 404 on /api/chat and throw a descriptive ApiError with the model name and the exact ollama pull command needed. - src/error-handler.ts: For API_ERROR type, return the error message directly instead of prefixing with 'API error: ', so the user-friendly 404 message is shown cleanly in the Obsidian notice. - tests/ollama-client.test.ts: Update 404 assertions to match the new descriptive error message. --- main.js | 14 +++++++++++++- src/error-handler.ts | 2 +- src/ollama-client.ts | 12 ++++++++++++ tests/ollama-client.test.ts | 4 ++-- 4 files changed, 28 insertions(+), 4 deletions(-) diff --git a/main.js b/main.js index 0411f67..cadff1a 100644 --- a/main.js +++ b/main.js @@ -8130,6 +8130,12 @@ var OllamaClient = class { signal: controller.signal }); if (!response.ok) { + if (response.status === 404) { + throw new ApiError( + `Model "${this.model}" not found. Run \`ollama pull ${this.model}\` first.`, + 404 + ); + } throw new ApiError(`Ollama API error: ${response.status}`, response.status); } if (!response.body) { @@ -8233,6 +8239,12 @@ var OllamaClient = class { signal: controller.signal }); if (!response.ok) { + if (response.status === 404) { + throw new ApiError( + `Model "${this.model}" not found. Run \`ollama pull ${this.model}\` first.`, + 404 + ); + } throw new ApiError(`Ollama API error: ${response.status}`, response.status); } const data = await response.json(); @@ -8849,7 +8861,7 @@ var ErrorHandler = class { case "network_error" /* NETWORK_ERROR */: return "Connection error. Please check if Ollama is running."; case "api_error" /* API_ERROR */: - return `API error: ${error.message}`; + return error.message; case "validation_error" /* VALIDATION_ERROR */: return this.getUserFriendlyValidationMessage(error); case "streaming_error" /* STREAMING_ERROR */: diff --git a/src/error-handler.ts b/src/error-handler.ts index 804e95f..ffb8261 100644 --- a/src/error-handler.ts +++ b/src/error-handler.ts @@ -47,7 +47,7 @@ export class ErrorHandler { case ErrorType.NETWORK_ERROR: return 'Connection error. Please check if Ollama is running.'; case ErrorType.API_ERROR: - return `API error: ${error.message}`; + return error.message; case ErrorType.VALIDATION_ERROR: return this.getUserFriendlyValidationMessage(error); case ErrorType.STREAMING_ERROR: diff --git a/src/ollama-client.ts b/src/ollama-client.ts index 74950ea..4f620be 100644 --- a/src/ollama-client.ts +++ b/src/ollama-client.ts @@ -146,6 +146,12 @@ export class OllamaClient { }); if (!response.ok) { + if (response.status === 404) { + throw new ApiError( + `Model "${this.model}" not found. Run \`ollama pull ${this.model}\` first.`, + 404 + ); + } throw new ApiError(`Ollama API error: ${response.status}`, response.status); } @@ -270,6 +276,12 @@ export class OllamaClient { }); if (!response.ok) { + if (response.status === 404) { + throw new ApiError( + `Model "${this.model}" not found. Run \`ollama pull ${this.model}\` first.`, + 404 + ); + } throw new ApiError(`Ollama API error: ${response.status}`, response.status); } diff --git a/tests/ollama-client.test.ts b/tests/ollama-client.test.ts index 2f3a95d..3f891fd 100755 --- a/tests/ollama-client.test.ts +++ b/tests/ollama-client.test.ts @@ -214,7 +214,7 @@ describe('OllamaClient', () => { mockFetch.mockResolvedValue({ ok: false, status: 404 }); await expect(client.streamChatAsPromise(mockMessages, mockTools)).rejects.toThrow( - 'Ollama API error: 404' + 'Model "llama3" not found. Run \`ollama pull llama3\` first.' ); }); @@ -418,7 +418,7 @@ describe('OllamaClient', () => { /* consume */ } })() - ).rejects.toThrow('Ollama API error: 404'); + ).rejects.toThrow('Model "llama3" not found. Run \`ollama pull llama3\` first.'); }); });