fix(webconfig): report a missing endpoint honestly

A bare 404 carries no body, so r.json() rejected and the parse failure escaped
with no HTTP status attached. Every caller then had to treat "this route does
not exist" as an ambiguous network failure — for the CLI that meant ~14 seconds
of polling before reporting a lost connection, which is the wrong diagnosis and
the wrong wait.

api() now substitutes an empty object when an *error* response has no readable
JSON, so the status survives onto the error. Successful responses must still
parse, or a captive portal's HTML would sail through as valid config.

The CLI names the case outright: firmware without /api/cli says so in 100ms
instead of retrying a route that will never exist.
This commit is contained in:
agessaman
2026-08-07 23:01:52 -07:00
parent b72b02f55b
commit 33d8766d48
+11 -1
View File
@@ -592,7 +592,14 @@ function api(path,opts){
}
return fetch(path,opts).then(function(r){
if(r.status===401){showLogin();throw new Error("auth")}
return r.json().then(function(j){
// An error response need not carry JSON — a bare 404 from handleNotFound
// has an empty body. Letting the parse failure escape would strip the HTTP
// status off the error and leave callers unable to tell "no such endpoint"
// from "the network dropped". Successful responses must still parse.
return r.json().catch(function(){
if(r.ok)throw new Error("unreadable reply from the node");
return {};
}).then(function(j){
if(!r.ok&&r.status!==202){
// Carry the HTTP status and any batch reqid so callers can tell a
// definite rejection (400/409/413) from an ambiguous network failure.
@@ -1936,6 +1943,9 @@ function cliRun(cmds){
cliPoll(reqid,cmds,0,status,0,0);
}).catch(function(e){
if(e.message==="auth"){cliBusy(false);status.remove();return}
// No such endpoint: this firmware predates the console (or was built
// without it). Say so instead of retrying a route that will never exist.
if(e.status===404){cliEnd(status,"This firmware has no console endpoint — nothing was sent.");return}
if(e.status===409&&e.reqid!==reqid){cliEnd(status,"Another sequence is still running — retry shortly.");return}
if(e.status===400||e.status===413){cliEnd(status,e.message||"Rejected by the node.");return}
// Ambiguous: the request may have landed even though the reply was lost.