From 18a84ef4cbdfd06667c4066724beef8ea0d80aec Mon Sep 17 00:00:00 2001 From: flemming-it Date: Tue, 7 Jul 2026 19:18:24 +0200 Subject: [PATCH] fix: clear Ollama-unreachable error naming the endpoint + fix hint Signed-off-by: flemming-it --- src/lib.rs | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index c13d8f1..54d729d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -35,7 +35,7 @@ pub fn invoke(_ctx: Context, inputs: Inputs) -> Result { prompt: &prompt, }; let result = crate::llm::chat_with_identity(&client, ¶ms) - .map_err(|e| ModuleError::internal(e.to_string()))?; + .map_err(|e| llm_error_to_module_error(e, &endpoint, &model))?; Ok(Outputs::new() .with_text("response", result.response) @@ -51,6 +51,35 @@ fn payload_text(p: &Payload) -> Option { } } +/// Turn a transport/protocol error into a message that names the +/// likely cause and the fix, instead of a raw `ConnectionRefused`. +/// The endpoint is Ollama-shaped by default, so a connect failure +/// almost always means Ollama isn't running or the model isn't +/// pulled. +fn llm_error_to_module_error(e: crate::llm::LlmError, endpoint: &str, model: &str) -> ModuleError { + use crate::llm::LlmError; + match e { + LlmError::Http(detail) => ModuleError::internal(format!( + "LLM endpoint {endpoint} not reachable ({detail}). Is Ollama running? \ + Start it with `ollama serve`, then pull the model with `ollama pull {model}`. \ + If the LLM runs elsewhere, set the `endpoint` input to its /api URL." + )), + LlmError::Status(404) => ModuleError::internal(format!( + "LLM endpoint {endpoint} returned 404 for model '{model}' — the model is \ + likely not pulled. Run `ollama pull {model}` (or check the model name)." + )), + LlmError::Status(code) => ModuleError::internal(format!( + "LLM endpoint {endpoint} returned HTTP {code} for model '{model}'." + )), + LlmError::Decode(detail) => ModuleError::internal(format!( + "LLM response from {endpoint} was not valid Ollama JSON: {detail}" + )), + LlmError::MissingInput(name) => ModuleError::invalid_input(format!( + "missing required input '{name}'" + )), + } +} + #[cfg(target_arch = "wasm32")] fn make_client() -> WakiClient { WakiClient