5294e72024937d44e0e13e4f55ba408f351c2ac2
hiram
  Tue Apr 16 10:27:14 2019 -0700
updated error messages and error testing refs #18869

diff --git src/hg/hubApi/apiUtils.c src/hg/hubApi/apiUtils.c
index 56e4a2c..13381eb 100644
--- src/hg/hubApi/apiUtils.c
+++ src/hg/hubApi/apiUtils.c
@@ -3,48 +3,58 @@
 #include "dataApi.h"
 
 void apiFinishOutput(int errorCode, char *errorString, struct jsonWrite *jw)
 /* finish json output, potential output an error code other than 200 */
 {
 /* this is the first time any output to stdout has taken place for
  * json output, therefore, start with the appropriate header.
  */
 puts("Content-Type:application/json");
 /* potentially with an error code return in the header */
 if (errorCode)
     {
     char errString[2048];
     safef(errString, sizeof(errString), "Status: %d %s",errorCode,errorString);
     puts(errString);
-    if (429 == errorCode)
+    if (err429 == errorCode)
 	puts("Retry-After: 30");
     }
 puts("\n");
 
+if (debug)
+    {
+    char sizeString[64];
+    unsigned long long vmPeak = currentVmPeak();
+    sprintLongWithCommas(sizeString, vmPeak);
+    jsonWriteString(jw, "vmPeak", sizeString);
+    }
+
 jsonWriteObjectEnd(jw);
 fputs(jw->dy->string,stdout);
 }	/*	void apiFinishOutput(int errorCode, char *errorString, ... ) */
 
 void apiErrAbort(int errorCode, char *errString, char *format, ...)
 /* Issue an error message in json format, and exit(0) */
 {
 char errMsg[2048];
 va_list args;
 va_start(args, format);
 vsnprintf(errMsg, sizeof(errMsg), format, args);
 struct jsonWrite *jw = apiStartOutput();
 jsonWriteString(jw, "error", errMsg);
+jsonWriteNumber(jw, "statusCode", errorCode);
+jsonWriteString(jw, "statusMessage", errString);
 apiFinishOutput(errorCode, errString, jw);
 exit(0);
 }
 
 struct jsonWrite *apiStartOutput()
 /* begin json output with standard header information for all requests */
 {
 time_t timeNow = time(NULL);
 // struct tm tm;
 // gmtime_r(&timeNow, &tm);
 struct jsonWrite *jw = jsonWriteNew();
 jsonWriteObjectStart(jw, NULL);
 // not recommended: jsonWriteString(jw, "apiVersion", "v"CGI_VERSION);
 // not needed jsonWriteString(jw, "source", "UCSantaCruz");
 jsonWriteDateFromUnix(jw, "downloadTime", (long long) timeNow);
@@ -185,31 +195,31 @@
 return columnCount;
 }
 
 struct trackHub *errCatchTrackHubOpen(char *hubUrl)
 /* use errCatch around a trackHub open in case it fails */
 {
 struct trackHub *hub = NULL;
 struct errCatch *errCatch = errCatchNew();
 if (errCatchStart(errCatch))
     {
     hub = trackHubOpen(hubUrl, "");
     }
 errCatchEnd(errCatch);
 if (errCatch->gotError)
     {
-    apiErrAbort(404, "Not Found", "error opening hubUrl: '%s', '%s'", hubUrl,  errCatch->message->string);
+    apiErrAbort(err404, err404Msg, "error opening hubUrl: '%s', '%s'", hubUrl,  errCatch->message->string);
     }
 errCatchFree(&errCatch);
 return hub;
 }
 
 struct trackDb *obtainTdb(struct trackHubGenome *genome, char *db)
 /* return a full trackDb fiven the hub genome pointer, or ucsc database name */
 {
 struct trackDb *tdb = NULL;
 if (db)
     tdb = hTrackDb(db);
 else
     {
     tdb = trackHubTracksForGenome(genome->trackHub, genome);
     tdb = trackDbLinkUpGenerations(tdb);
@@ -257,30 +267,77 @@
 struct bbiFile *bigFileOpen(char *trackType, char *bigDataUrl)
 /* open bigDataUrl for correct trackType and error catch if failure */
 {
 struct bbiFile *bbi = NULL;
 struct errCatch *errCatch = errCatchNew();
 if (errCatchStart(errCatch))
     {
 if (allowedBigBedType(trackType))
     bbi = bigBedFileOpen(bigDataUrl);
 else if (startsWith("bigWig", trackType))
     bbi = bigWigFileOpen(bigDataUrl);
     }
 errCatchEnd(errCatch);
 if (errCatch->gotError)
     {
-    apiErrAbort(404, "Not Found", "error opening bigFile URL: '%s', '%s'", bigDataUrl,  errCatch->message->string);
+    apiErrAbort(err404, err404Msg, "error opening bigFile URL: '%s', '%s'", bigDataUrl,  errCatch->message->string);
     }
 errCatchFree(&errCatch);
 return bbi;
 }
 
 int chromInfoCmp(const void *va, const void *vb)
 /* Compare to sort based on size */
 {
 const struct chromInfo *a = *((struct chromInfo **)va);
 const struct chromInfo *b = *((struct chromInfo **)vb);
 int dif;
 dif = (long) a->size - (long) b->size;
 return dif;
 }
+
+#ifdef NOT
+unsigned largestChrom(char *db, char **nameReturn, int *chromCount)
+/* return the length and get the chrom name for the largest chrom
+ * from chromInfo table.  For use is sample getData URLs
+ */
+{
+char query[1024];
+struct sqlConnection *conn = hAllocConn(db);
+sqlSafef(query, sizeof(query), "select chrom,size from chromInfo order by size desc limit 1");
+struct sqlResult *sr = sqlGetResult(conn, query);
+char **row = sqlNextRow(sr);
+unsigned length = 0;
+if (row)
+   {
+   *nameReturn = cloneString(row[0]);
+   length = sqlLongLong(row[1]);
+   }
+sqlFreeResult(&sr);
+if (chromCount)
+    {
+    sqlSafef(query, sizeof(query), "select count(*) from chromInfo");
+    *chromCount = sqlQuickNum(conn, query);
+    }
+hFreeConn(&conn);
+return length;
+}/*static unsigned largestChrom(char *db, char **nameReturn, int *chromCount)*/
+
+unsigned largestChromInfo(struct chromInfo *ci, char **chromName)
+/* find largest chrom in this chromInfo, return name and size */
+{
+unsigned size = 0;
+char *name = NULL;
+struct chromInfo *el;
+for (el = ci; el; el = el->next)
+    {
+    if (el->size > size)
+	{
+	size = el->size;
+	name = el->chrom;
+	}
+    }
+if (chromName)
+    *chromName = name;
+return size;
+}	/* unsigned largestChromInfo(struct chromInfo *ci, char **chromName) */
+#endif