4c63c358efeed6aaf99fad3993e63123cd6a0f79
angie
  Wed May 22 10:30:58 2019 -0700
Use errCatch to avoid errAborts when re-saving sessions whose db has been removed.  refs #22440

diff --git src/hg/hgSession/hgSession.c src/hg/hgSession/hgSession.c
index 1532a6a..d2ace25 100644
--- src/hg/hgSession/hgSession.c
+++ src/hg/hgSession/hgSession.c
@@ -26,30 +26,31 @@
 #include "web.h"
 #include "hdb.h"
 #include "ra.h"
 #include "wikiLink.h"
 #include "customTrack.h"
 #include "customFactory.h"
 #include "udc.h"
 #include "hgSession.h"
 #include "hgConfig.h"
 #include "sessionThumbnail.h"
 #include "filePath.h"
 #include "obscure.h"
 #include "trashDir.h"
 #include "hubConnect.h"
 #include "trackHub.h"
+#include "errCatch.h"
 
 void usage()
 /* Explain usage and exit. */
 {
 errAbort(
   "hgSession - Interface with wiki login and do session saving/loading.\n"
   "usage:\n"
   "    hgSession <various CGI settings>\n"
   );
 }
 
 /* Global variables. */
 struct cart *cart;
 char *excludeVars[] = {"Submit", "submit", hgsSessionDataDbSuffix, NULL};
 struct slName *existingSessionNames = NULL;
@@ -717,31 +718,45 @@
 char *cartVis = cartOptionalString(cart, track);
 if (cartVis == NULL)
     {
     if (dy)
         dyStringPrintf(dy,"&%s=%s", track, hStringFromTv(tdbVis));
     else
         printf("%s %s\n", track, hStringFromTv(tdbVis));
     }
 }
 
 static void outDefaultTracks(struct cart *cart, struct dyString *dy)
 /* Output the default trackDb visibility for all tracks
  * in trackDb if the track is not mentioned in the cart. */
 {
 char *database = cartString(cart, "db");
-struct trackDb *tdb = hTrackDb(database);
+struct trackDb *tdb = NULL;
+// Some old sessions reference databases that are no longer present, and that triggers an errAbort
+// when calling hgTrackDb.  Just move on instead of errAborting.
+struct errCatch *errCatch = errCatchNew();
+if (errCatchStart(errCatch))
+    tdb = hTrackDb(database);
+errCatchEnd(errCatch);
+if (errCatch->gotError)
+    {
+    fprintf(stderr, "outDefaultTracks: Error from hTrackDb: '%s'; Continuing...",
+            errCatch->message->string);
+    tdb = NULL;
+    }
+errCatchFree(&errCatch);
+
 struct hash *parentHash = newHash(5);
 
 for(; tdb; tdb = tdb->next)
     {
     struct trackDb *parent = tdb->parent;
     if (parent) 
         {
         if (hashLookup(parentHash, parent->track) == NULL)
             {
             hashStore(parentHash, parent->track);
             if (parent->isShow)
                 outIfNotPresent(cart, dy, parent->track, tvShow);
             }
         }
     if (tdb->visibility != tvHide)
@@ -1562,31 +1577,41 @@
  * so that customTrash tables will be moved to customData* databases and trash paths
  * will be replaced with userdata (hg.conf sessionDataDir) paths.
  * NOTE: this is not intended to be reachable by the UI; it is for a script to update
  * old sessions to use the new sessionData locations. */
 {
 if (userName == NULL)
     return "Unable to re-save session -- please log in and try again.";
 struct sqlConnection *conn = hConnectCentral();
 char *sessionName = cloneString(trimSpaces(cartString(cart, hgsNewSessionName)));
 char *encUserName = cgiEncodeFull(userName);
 char *encSessionName = cgiEncodeFull(sessionName);
 boolean shareSession = isSessionShared(conn, encUserName, encSessionName);
 cartLoadUserSession(conn, userName, sessionName, cart, NULL, actionVar);
 // Don't cartCopyCustomComposites because we're not going to make any track collection changes
 hubConnectLoadHubs(cart);
+// Some old sessions reference databases that are no longer present, and that triggers an errAbort
+// when cartHideDefaultTracks calls hgTrackDb.  Don't let that stop the process of updating other
+// stuff in the session.
+struct errCatch *errCatch = errCatchNew();
+if (errCatchStart(errCatch))
     cartHideDefaultTracks(cart);
+errCatchEnd(errCatch);
+if (errCatch->gotError)
+    fprintf(stderr, "doReSaveSession: Error from cartHideDefaultTracks: '%s'; Continuing...",
+            errCatch->message->string);
+errCatchFree(&errCatch);
 struct dyString *dyMessage = dyStringNew(1024);
 dyStringPrintf(dyMessage,
                "Re-saved settings from user <B>%s</B>'s session <B>%s</B> "
                "that %s be shared with others.  %s %s",
 	       userName, htmlEncode(sessionName), (shareSession ? "may" : "may not"),
 	       getSessionLink(userName, encSessionName),
 	       getSessionEmailLink(encUserName, encSessionName));
 cartCheckForCustomTracks(cart, dyMessage);
 int useCount = saveCartAsSession(conn, encUserName, encSessionName, shareSession);
 if (useCount <= INITIAL_USE_COUNT)
     errAbort("Expected useCount of at least %d after re-saving session for "
              "userName='%s', sessionName='%s', but got %d",
              INITIAL_USE_COUNT+1, encUserName, encSessionName, useCount);
 hDisconnectCentral(&conn);
 return dyStringCannibalize(&dyMessage);