f880f8b822d19c049867d38998c93a03566ba13f
hiram
  Wed Aug 12 13:26:46 2026 -0700
fixing up errors found in code review refs #37946

diff --git src/hg/hubApi/liftOver.c src/hg/hubApi/liftOver.c
index eec643b08d3..10d689a49ad 100644
--- src/hg/hubApi/liftOver.c
+++ src/hg/hubApi/liftOver.c
@@ -188,67 +188,74 @@
 char *url = "https://genome.ucsc.edu/cgi-bin/hubApi/liftOver/loginStatus";
 int sd = netOpenHttpExt(url, "GET", reqHeader->string);
 dyStringFree(&reqHeader);
 if (sd < 0)
     return FALSE;
 
 char *redirectedUrl = NULL;
 if (!netSkipHttpHeaderLinesWithRedirect(sd, url, &redirectedUrl))
     {
     close(sd);
     return FALSE;
     }
 
 struct dyString *body = netSlurpFile(sd);
 close(sd);
-struct jsonElement *json = jsonParse(body->string);
-dyStringFree(&body);
-if (json == NULL)
-    return FALSE;
 
+boolean ok = FALSE;
+struct errCatch *errCatch = errCatchNew();
+if (errCatchStart(errCatch))
+    {
+    struct jsonElement *json = jsonParse(body->string);
     char *email = jsonStringField(json, "email");
     char *realName = jsonStringField(json, "realName");
     *retEmail = cloneString(email ? email : "");
     *retRealName = cloneString(realName ? realName : "");
-return TRUE;
+    ok = TRUE;
+    }
+errCatchEnd(errCatch);
+errCatchFree(&errCatch);
+dyStringFree(&body);
+return ok;
 }
 
 static void loginStatus()
 /* output current user login status as JSON */
 {
 /* wikiLinkUserName() handles all cookie validation internally */
 char *userName = wikiLinkUserName();
 struct jsonWrite *jw = apiStartOutput();
 char hgLoginLink[2048];
 boolean privateHost = hIsPrivateHost();
 /* can not use hgcentral hglogin from hgwdev/genome-test */
 if (privateHost)
     safef(hgLoginLink, sizeof(hgLoginLink), "%shgLogin", hLocalHostCgiBinUrl());
 else
     safef(hgLoginLink, sizeof(hgLoginLink), "%shgLogin", hLoginHostCgiBinUrl());
 
 if (userName != NULL)
     {
     // Get both email and realName from gbMembers table
     char *email = NULL;
     char *realName = NULL;
 
     if (inUcscEduDomain() && !onGenomeRRMachine())
         {
         // dev sandboxes, hgwbeta, etc: no local grants on gbMembers,
         // relay to genome.ucsc.edu instead
-        fetchGbMembersFromCentral(userName, &email, &realName);
+        if (!fetchGbMembersFromCentral(userName, &email, &realName))
+            warn("loginStatus: failed to fetch email/realName from genome.ucsc.edu relay for user '%s'", userName);
         }
     else
         {
         // RR machines, and anything entirely outside ucsc.edu: unchanged
         struct sqlConnection *sc = hConnectCentral();
         struct dyString *query = sqlDyStringCreate("select email, realName from gbMembers where userName = '%s'", userName);
         struct sqlResult *sr = sqlGetResult(sc, dyStringCannibalize(&query));
         char **row = sqlNextRow(sr);
 
         if (row != NULL)
             {
             email = cloneString(row[0] ? row[0] : "");
             realName = cloneString(row[1] ? row[1] : "");
             }
         sqlFreeResult(&sr);
@@ -407,31 +414,31 @@
 
 char *fromGenome = cgiOptionalString(argFromGenome);
 char *toGenome = cgiOptionalString(argToGenome);
 char *chrom = cgiOptionalString(argChrom);
 char *start = cgiOptionalString(argStart);
 char *end = cgiOptionalString(argEnd);
 
 if (isEmpty(fromGenome) || isEmpty(toGenome) || isEmpty(chrom) || isEmpty(start) || isEmpty(end))
     apiErrAbort(err400, err400Msg, "must have all arguments: %s, %s, %s, %s, %s  for endpoint '/liftOver", argFromGenome, argToGenome, argChrom, argStart, argEnd);
 
 unsigned uStart = 0;
 unsigned uEnd = 0;
 uStart = sqlUnsigned(start);
 uEnd = sqlUnsigned(end);
 if (uEnd < uStart)
-    apiErrAbort(err400, err400Msg, "given start coordinate %u is greater than given end coordinate", uStart, uEnd);
+    apiErrAbort(err400, err400Msg, "given start coordinate %u is greater than given end coordinate %u", uStart, uEnd);
 
 struct dbDb *fromDb = hDbDb(fromGenome);
 if (fromDb == NULL)
     {
     fromDb = genarkLiftOverDb(fromGenome);
     }
 if (fromDb == NULL)
     apiErrAbort(err400, err400Msg, "can not find 'fromGenome=%s' for endpoint '/liftOver", fromGenome);
 struct dbDb *toDb = hDbDb(toGenome);
 if (toDb == NULL)
     {
     toDb = genarkLiftOverDb(toGenome);
     }
 if (toDb == NULL)
     apiErrAbort(err400, err400Msg, "can not find 'toGenome=%s' for endpoint '/liftOver", toGenome);
@@ -476,39 +483,42 @@
 char *userId = findCookieData(cookieName);
 if (isEmpty(userId))
     apiErrAbort(err400, err400Msg, "can not find required inputs for endpoint '/liftRequest");
 
 /* verify (again) that the requested assemblies actually exist */
 struct dbDb *fromDb = hDbDb(fromGenome);
 if (fromDb == NULL)
     {
     fromDb = genarkLiftOverDb(fromGenome);
     }
 struct dbDb *toDb = hDbDb(toGenome);
 if (toDb == NULL)
     {
     toDb = genarkLiftOverDb(toGenome);
     }
-if ( (fromDb == NULL) || (fromDb == NULL) )
+if ( (fromDb == NULL) || (toDb == NULL) )
     {
     if ( (fromDb == NULL) && (toDb == NULL) )
 	    apiErrAbort(err400, err400Msg, "can not find either 'fromGenome=%s' or 'toGenome=%s' for endpoint '/liftOver", fromGenome, toGenome);
         else
+	    {
+	    if (fromDb == NULL)
 		apiErrAbort(err400, err400Msg, "can not find 'fromoGenome=%s' for endpoint '/liftOver", fromGenome);
-    if (toDb == NULL)
+	    else
 		apiErrAbort(err400, err400Msg, "can not find 'toGenome=%s' for endpoint '/liftOver", toGenome);
 	    }
+    }
 
 /* Record the request in the ottoRequest table: duplicate-row guard, daily
  * rate-limit guard, then an atomic insert.  Done locally (this host has
  * hgcentral write grants) or relayed to genome.ucsc.edu (it doesn't) --
  * see inUcscEduDomain()/onGenomeRRMachine(). */
 char *ottoStatus;
 if (inUcscEduDomain() && !onGenomeRRMachine())
     ottoStatus = relaySubmitOttoRequest("liftOver", fromGenome, toGenome, email, comment);
 else
     ottoStatus = submitOttoRequest("liftOver", fromGenome, toGenome, email, comment);
 
 if (sameString(ottoStatus, "duplicate"))
     apiErrAbort(err409, err409Msg,
         "A request for %s <-> %s has already been submitted "
         "and is on record.  Duplicates are not accepted.",