diff --git a/src/lib.rs b/src/lib.rs index d32493b..4e42325 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -44,7 +44,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("translation", result.response) @@ -55,6 +55,32 @@ pub fn invoke(_ctx: Context, inputs: Inputs) -> Result { .with_text("model_digest", result.model_digest.unwrap_or_default())) } +/// Turn a transport/protocol error into a message that names the +/// likely cause and the fix, instead of a raw `ConnectionRefused`. +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}'")) + } + } +} + fn build_prompt(source: &str, target: &str, text: &str) -> String { if source.is_empty() { format!(