f3009e2f9d911795bd1d13a0f95bbbee46309f83
galt
  Sun Nov 14 18:54:39 2021 -0800
Adding warn-and-continue option to hgCustom. Motivation is to support https warnings but will be useful more widely. refs #28458

diff --git src/hg/lib/customTrack.c src/hg/lib/customTrack.c
index 43ba822..702b7f7 100644
--- src/hg/lib/customTrack.c
+++ src/hg/lib/customTrack.c
@@ -719,45 +719,47 @@
 /* CT update is needed if database has been enabled since
  * the custom tracks in this file were created.  The only way to check is
  * by file mod time, unless we add the enable time to
  * browser metadata somewhere */
 {
 if (!ctFile || !fileExists(ctFile))
     return FALSE;
 return cfgModTime() > fileModTime(ctFile);
 }
 
 struct customTrack *customTracksParseCartDetailed(char *genomeDb, struct cart *cart,
 					  struct slName **retBrowserLines,
 					  char **retCtFileName,
                                           struct customTrack **retReplacedCts,
                                           int *retNumAdded,
-                                          char **retErr)
+                                          char **retErr,
+                                          boolean *retWarnOnly)
 /* Figure out from cart variables where to get custom track text/file.
  * Parse text/file into a custom set of tracks.  Lift if necessary.
  * If retBrowserLines is non-null then it will return a list of lines
  * starting with the word "browser".  If retCtFileName is non-null then
  * it will return the custom track filename.  If any existing custom tracks
  * are replaced with new versions, they are included in replacedCts.
  *
  * If there is a syntax error in the custom track this will report the
  * error */
 {
 #define CT_CUSTOM_FILE_BIN_VAR  CT_CUSTOM_FILE_VAR "__binary"
 #define CT_CUSTOM_DOC_FILE_BIN_VAR  CT_CUSTOM_DOC_FILE_VAR "__binary"
 int numAdded = 0;
 char *err = NULL;
+boolean warnOnly = FALSE;
 
 /* the hgt.customText and hgt.customFile variables contain new custom
  * tracks that have not yet been parsed */
 
 char *customText = cartOptionalString(cart, CT_CUSTOM_TEXT_ALT_VAR);
 /* parallel CGI variable, used by hgCustom, to allow javascript */
 if (!customText)
     customText = cartOptionalString(cart, CT_CUSTOM_TEXT_VAR);
 char *fileName = NULL;
 struct slName *browserLines = NULL;
 customText = skipLeadingSpaces(customText);
 
 fileName = cartOptionalString(cart, CT_CUSTOM_FILE_NAME_VAR);
 char *fileContents = cartOptionalString(cart, CT_CUSTOM_FILE_VAR);
 if (isNotEmpty(fileName))
@@ -854,34 +856,36 @@
         {
         char *msg = cloneString(errCatch->message->string);
 
         if (fileName && fileName[0])
             {
             struct dyString *ds = dyStringNew(0);
             dyStringPrintf(ds, "File '%s' - %s", fileName, msg);
             err = dyStringCannibalize(&ds);
             }
         else
             err = msg;
         }
     else
 	{
 	err = customTrackUnavailableErrsFromList(newCts);
-	if (err)
-	    newCts = NULL;  /* do not save the unhappy remote cts*/
         if (isNotEmpty(errCatch->message->string))
             err = catTwoStrings(emptyForNull(err), errCatch->message->string);
+        if (err)
+	    {
+	    warnOnly = TRUE;
+	    }
 	}
     errCatchFree(&errCatch);
     }
 
 /* the 'ctfile_$db' variable contains a filename from the trash directory.
  * The file is created by hgCustom or hgTables after the custom track list
  * is created.  The filename may be reused.  The file contents are
  * custom tracks in "internal format" that have already been parsed */
 
 char *ctFileName = NULL;
 struct customTrack *ctList = NULL, *replacedCts = NULL;
 struct customTrack *nextCt = NULL;
 boolean removedCt = FALSE;
 
 /* load existing custom tracks from trash file */
@@ -1001,42 +1005,44 @@
 cartRemove(cart, CT_CUSTOM_FILE_VAR);
 cartRemove(cart, CT_CUSTOM_FILE_NAME_VAR);
 cartRemove(cart, CT_CUSTOM_FILE_BIN_VAR);
 cartRemove(cart, CT_CUSTOM_DOC_FILE_BIN_VAR);
 
 if (retCtFileName)
     *retCtFileName = ctFileName;
 if (retBrowserLines)
     *retBrowserLines = browserLines;
 if (retReplacedCts)
     *retReplacedCts = replacedCts;
 if (retNumAdded)
     *retNumAdded = numAdded;
 if (retErr)
     *retErr = err;
+if (retWarnOnly)
+    *retWarnOnly = warnOnly;
 return ctList;
 }
 
 struct customTrack *customTracksParseCart(char *genomeDb, struct cart *cart,
 					  struct slName **retBrowserLines,
 					  char **retCtFileName)
 /* Parse custom tracks from cart variables */
 {
 char *err = NULL;
 struct customTrack *ctList =
     customTracksParseCartDetailed(genomeDb, cart, retBrowserLines, retCtFileName,
-                                        NULL, NULL, &err);
+                                        NULL, NULL, &err, NULL);
 if (err)
     warn("%s", err);
 return ctList;
 }
 
 boolean customTracksExistDb(struct cart *cart, char *db, char **retCtFileName)
 /* determine if there are any custom tracks for db.  Cleanup from expired tracks */
 {
 char *ctFileVar = customTrackFileVar(db);
 char *ctFileName = cartOptionalString(cart, ctFileVar);
 if (ctFileName)
     {
     if (fileExists(ctFileName))
         {
         if (retCtFileName)