Skip to content

Harden Ollama HTTP and JSON error handling #4

Description

@LostOne1000

Priority

High

Summary

sendDataToApi() assumes that every Ollama response contains valid outer JSON, a string-valued response field, and valid model-generated JSON.

Several normal failures can therefore raise unhandled Lua exceptions:

  • Ollama is unavailable.
  • Ollama returns an HTTP error.
  • The selected model rejects image input.
  • The outer API response is malformed.
  • response_data.response is missing or has the wrong type.
  • The model response is not valid JSON.
  • Markdown cleanup encounters a nil value.

The current failure path also returns a string while callers assume the result is a table.

Relevant code

lightroom-llama.lrplugin/LrLlama.lua

local response_data = JSON:decode(response)
local rawResponse = response_data.response

rawResponse = string.gsub(rawResponse, ...)

local response_json = JSON:decode(rawResponse)
return response_json

Failure path:

return "Error: Failed to send data to the API."

Caller:

props.title = apiResponse.title
props.caption = apiResponse.caption

Expected behavior

Every Ollama or parsing failure should leave the dialog operational and provide a useful error message.

Implementation notes

Introduce a consistent result contract, for example:

{
    success = true,
    data = {
        title = "...",
        caption = "...",
        keywords = {}
    }
}

or:

{
    success = false,
    error = "Ollama returned invalid JSON."
}

Protect JSON operations with pcall() and validate each layer before continuing.

Validate:

  1. HTTP response exists.
  2. HTTP status indicates success.
  3. Outer response decodes to a table.
  4. response exists and is a string.
  5. Model response decodes to a table.

Acceptance criteria

  • Ollama connection failures do not raise an unhandled Lua exception.
  • Invalid outer JSON produces a recoverable error.
  • Missing response fields produce a recoverable error.
  • Invalid model-generated JSON produces a recoverable error.
  • The function never returns a string where the caller expects a response table.
  • The dialog returns to a usable state after every failure.
  • Error messages contain actionable information without exposing the image payload.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions