diff --git a/webui/index.html b/webui/index.html index 9ab44aa8..66e9a9f2 100644 --- a/webui/index.html +++ b/webui/index.html @@ -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.