mirror of
https://github.com/bryanthaboi/gen1recomp.git
synced 2026-08-17 19:24:01 +02:00
Fix mod update checks failing on non-JSON responses (#931)
The mod update and Find Mods feeds feed the raw HTTP body straight to Json.decode. When the endpoint hands back something that is not JSON (an HTML error page, a proxy/captive prompt, or a plain-text outage message like "Exceeded secondary rate limit" -- usually still HTTP 200), the decoder's "unexpected character 'E'" assert escaped through the pcall and became the error message, blaming the parser instead of the response. Add Json.describeUnexpected() as a pre-decode content-type guard: it returns nil for body shapes the endpoints actually publish (JSON object or array) and otherwise a short message naming what the server sent (HTML page / plain text / empty, with a preview). Wire it into ModUpdate.parseReleases and ModIndex.parse, so both the sync and async update-check paths surface the real answer instead of the parse error. HTTP status was already checked upstream by HostShell.httpGet (non-2xx becomes "HTTP <code> from <url> (...)"); this closes the remaining "2xx but not JSON" gap everywhere, including bridge platforms that expose no status or headers. Add regression tests for plain-text, HTML, and empty bodies; strengthen the ModIndex HTML soft-fail test. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -171,4 +171,26 @@ function Json.decode(s)
|
||||
return nil, v
|
||||
end
|
||||
|
||||
-- For an HTTP response that was meant to carry JSON but did not. Returns nil
|
||||
-- when `s` starts like a JSON object or array (the only shapes the update and
|
||||
-- index endpoints publish), otherwise a short message naming what the server
|
||||
-- actually sent -- so callers surface "the response was an HTML page/plain
|
||||
-- text, not JSON (it starts with ...)" instead of leaking the decoder's
|
||||
-- low-level "unexpected character 'E'" assert at the first byte of an error
|
||||
-- page or plain-text outage message.
|
||||
function Json.describeUnexpected(s)
|
||||
if type(s) ~= "string" then
|
||||
return "the response had no body to decode"
|
||||
end
|
||||
local first = s:match("^%s*(.)")
|
||||
if first == "{" or first == "[" then return nil end
|
||||
local preview = s:gsub("%s+", " "):gsub("^%s+", ""):gsub("%s+$", "")
|
||||
if preview == "" then
|
||||
return "the response was empty, not JSON"
|
||||
end
|
||||
if #preview > 60 then preview = preview:sub(1, 57) .. "..." end
|
||||
local kind = (first == "<") and "an HTML page" or "plain text"
|
||||
return ("the response was %s, not JSON (it starts with %q)"):format(kind, preview)
|
||||
end
|
||||
|
||||
return Json
|
||||
|
||||
Reference in New Issue
Block a user