08be525807ff3b3caf1233b9af15b010b950052b hiram Wed Sep 16 16:53:43 2026 -0700 gracefully manage bad response from api search requests refs #38365 diff --git src/hg/js/liftRequest.js src/hg/js/liftRequest.js index 061afc2e442..4da49bd3b9a 100644 --- src/hg/js/liftRequest.js +++ src/hg/js/liftRequest.js @@ -63,31 +63,36 @@ } else { liftPath = "https://hgdownload.soe.ucsc.edu/goldenPath/"; liftPath += asm1; } liftPath += "/liftOver/" + asm1 + "To"; liftPath += asm2.charAt(0).toUpperCase() + asm2.slice(1); liftPath += ".over.chain.gz"; return(liftPath); } function checkAssemblyCompatibility(asm1, asm2) { const url = "/cgi-bin/hubApi/liftOver/listExisting?fromGenome=" + encodeURIComponent(asm1) + ";" + "toGenome=" + encodeURIComponent(asm2); fetch(url) - .then(response => response.json()) + .then(response => { + if (!response.ok) { + throw new Error("listExisting request failed: " + response.status); + } + return response.json(); + }) .then(response => { // console.log(JSON.stringify(response, null, 2)); if (response.itemsReturned >= 1) { const liftPath1 = liftOverPath(asm1, asm2); const liftPath2 = liftOverPath(asm2, asm1); const browser1 = "/cgi-bin/hgTracks?db=" + asm1; const browser2 = "/cgi-bin/hgTracks?db=" + asm2; fileExists(liftPath1, function(exists) { if (exists) { document.getElementById("genome1Link").href = browser1; document.getElementById("genome1Link").textContent = assembly1Value; document.getElementById("genome1LiftOver").href = liftPath1; document.getElementById("genome1LiftOver").textContent = asm1 + " to " + asm2; @@ -385,31 +390,37 @@ showError("Error", errorMsg); }); } // end of function submitForm() function dismissLiftExists() { resetFormVisibility(); document.getElementById("genomeSearch1").value = ""; document.getElementById("genomeSearch2").value = ""; assembly1Value = ""; assembly2Value = ""; genome1 = ""; genome2 = ""; } function onSearchError(jqXHR, textStatus, errorThrown, term) { - return [{label: 'No genomes found', value: '', genome: '', disabled: true}]; + // This callback only fires when the search request itself failed + // (network error, non-2xx status, bad response) -- not for a + // legitimate zero-match result -- so say so rather than implying + // there were no matching genomes. + console.error("Genome search failed:", textStatus, errorThrown); + return [{label: 'Genome search is temporarily unavailable, please try again shortly', + value: '', genome: '', disabled: true}]; } document.addEventListener("DOMContentLoaded", () => { // Assembly 1 autocomplete let selectEle1 = document.getElementById("genomeLabel1"); let boundSelect1 = assembly1Select.bind(null, selectEle1); initSpeciesAutoCompleteDropdown('genomeSearch1', boundSelect1, "/cgi-bin/hubApi/findGenome?browser=mustExist;q=", null, null, onSearchError); let btn1 = document.getElementById("genomeSearchButton1"); btn1.addEventListener("click", () => { let val = document.getElementById("genomeSearch1").value; $("[id='genomeSearch1']").autocompleteCat("search", val); });