From f606840216d0026e9157b4b3ae702a12da781947 Mon Sep 17 00:00:00 2001 From: Shane McGovern Date: Mon, 10 Aug 2026 20:51:57 +0100 Subject: [PATCH] Handle non-JSON update responses Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- src/update/Check.lua | 9 +++++++-- tests/engine/update_check_tests.lua | 14 ++++++++++++++ 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/src/update/Check.lua b/src/update/Check.lua index f9d6bc67..c485336c 100644 --- a/src/update/Check.lua +++ b/src/update/Check.lua @@ -52,8 +52,13 @@ end -- falls back to require. function Check.parseRelease(jsonText, Json) Json = Json or require("src.link.Json") - local doc = Json.decode(jsonText) - if type(doc) ~= "table" or not doc.tag_name then + local notJson = Json.describeUnexpected(jsonText) + if notJson then return nil, notJson end + local doc, decodeErr = Json.decode(jsonText) + if type(doc) ~= "table" then + return nil, decodeErr or "no tag_name in release json" + end + if not doc.tag_name then return nil, "no tag_name in release json" end local version = stripV(doc.tag_name) diff --git a/tests/engine/update_check_tests.lua b/tests/engine/update_check_tests.lua index 698c5c9f..193ab118 100644 --- a/tests/engine/update_check_tests.lua +++ b/tests/engine/update_check_tests.lua @@ -47,6 +47,20 @@ eq(bad, nil, "non-X.Y.Z tag rejected") check(badErr ~= nil, "rejection carries an error string") eq(Check.parseRelease(Json.encode({ foo = 1 })), nil, "missing tag_name rejected") +-- Network failures can return a plain-text or HTML body instead of JSON. The +-- launcher must describe that response rather than leaking the decoder's +-- low-level "unexpected character 'E'" assertion. +do + local release, err = Check.parseRelease("Error: API rate limit exceeded") + check(release == nil and tostring(err):find("not JSON", 1, true) ~= nil, + "plain-text update failure is reported as non-JSON") + release, err = Check.parseRelease("502 Bad Gateway") + check(release == nil and tostring(err):find("HTML", 1, true) ~= nil, + "HTML update failure is identified") + check(tostring(err):find("unexpected character", 1, true) == nil, + "decoder assertion is not exposed") +end + -- parseSums: shasum -a 256 format, tolerating the '*' binary marker, a './' -- prefix and CRLF line endings; unrelated lines are skipped local sums =