5294e72024937d44e0e13e4f55ba408f351c2ac2 hiram Tue Apr 16 10:27:14 2019 -0700 updated error messages and error testing refs #18869 diff --git src/hg/hubApi/getData.c src/hg/hubApi/getData.c index 11a7513..ab5e0ab 100644 --- src/hg/hubApi/getData.c +++ src/hg/hubApi/getData.c @@ -90,31 +90,31 @@ if (sqlColumnExists(conn, sqlTable, "txStart")) // track type genePred { safef(startName, sizeof(startName), "txStart"); safef(endName, sizeof(endName), "txEnd"); } /* no chrom specified, return entire table */ if (isEmpty(chrom)) sqlSafef(query, sizeof(query), "select * from %s", sqlTable); else if (0 == (start + end)) /* have chrom, no start,end == full chr */ { // boolean useTname = FALSE; /* need to extend the chrom column check to allow tName also */ if (! sqlColumnExists(conn, sqlTable, chromName)) - apiErrAbort(400, "Bad Request", "track '%s' is not a position track, request track without chrom specification, genome: '%s'", track, db); + apiErrAbort(err400, err400Msg, "track '%s' is not a position track, request track without chrom specification, genome: '%s'", track, db); jsonWriteString(jw, "chrom", chrom); struct chromInfo *ci = hGetChromInfo(db, chrom); jsonWriteNumber(jw, "start", (long long)0); jsonWriteNumber(jw, "end", (long long)ci->size); sqlSafef(query, sizeof(query), "select * from %s where %s='%s'", sqlTable, chromName, chrom); } else /* fully specified chrom:start-end */ { jsonWriteString(jw, "chrom", chrom); jsonWriteNumber(jw, "start", (long long)start); jsonWriteNumber(jw, "end", (long long)end); if (startsWith("wig", tdb->type)) { wigTableDataOutput(jw, db, sqlTable, chrom, start, end); @@ -272,71 +272,71 @@ jsonWriteObjectEnd(jw); } static void getHubTrackData(char *hubUrl) /* return data from a hub track, optionally just one chrom data, * optionally just one section of that chrom data */ { char *genome = cgiOptionalString("genome"); char *track = cgiOptionalString("track"); char *chrom = cgiOptionalString("chrom"); char *start = cgiOptionalString("start"); char *end = cgiOptionalString("end"); if (isEmpty(genome)) - apiErrAbort(400, "Bad Request", "missing genome=<name> for endpoint '/getData/track' given hubUrl='%s'", hubUrl); + apiErrAbort(err400, err400Msg, "missing genome=<name> for endpoint '/getData/track' given hubUrl='%s'", hubUrl); if (isEmpty(track)) - apiErrAbort(400, "Bad Request", "missing track=<name> for endpoint '/getData/track' given hubUrl='%s'", hubUrl); + apiErrAbort(err400, err400Msg, "missing track=<name> for endpoint '/getData/track' given hubUrl='%s'", hubUrl); struct trackHub *hub = errCatchTrackHubOpen(hubUrl); struct trackHubGenome *hubGenome = NULL; for (hubGenome = hub->genomeList; hubGenome; hubGenome = hubGenome->next) { if (sameString(genome, hubGenome->name)) break; } if (NULL == hubGenome) - apiErrAbort(400, "Bad Request", "failed to find specified genome=%s for endpoint '/getData/track' given hubUrl '%s'", genome, hubUrl); + apiErrAbort(err400, err400Msg, "failed to find specified genome=%s for endpoint '/getData/track' given hubUrl '%s'", genome, hubUrl); struct trackDb *tdb = obtainTdb(hubGenome, NULL); if (NULL == tdb) - apiErrAbort(400, "Bad Request", "failed to find a track hub definition in genome=%s for endpoint '/getData/track' given hubUrl='%s'", genome, hubUrl); + apiErrAbort(err400, err400Msg, "failed to find a track hub definition in genome=%s for endpoint '/getData/track' given hubUrl='%s'", genome, hubUrl); struct trackDb *thisTrack = findTrackDb(track, tdb); if (NULL == thisTrack) - apiErrAbort(400, "Bad Request", "failed to find specified track=%s in genome=%s for endpoint '/getData/track' given hubUrl='%s'", track, genome, hubUrl); + apiErrAbort(err400, err400Msg, "failed to find specified track=%s in genome=%s for endpoint '/getData/track' given hubUrl='%s'", track, genome, hubUrl); char *bigDataUrl = trackDbSetting(thisTrack, "bigDataUrl"); struct bbiFile *bbi = bigFileOpen(thisTrack->type, bigDataUrl); if (NULL == bbi) - apiErrAbort(400, "Bad Request", "track type %s management not implemented yet TBD track=%s in genome=%s for endpoint '/getData/track' given hubUrl='%s'", track, genome, hubUrl); + apiErrAbort(err400, err400Msg, "track type %s management not implemented yet TBD track=%s in genome=%s for endpoint '/getData/track' given hubUrl='%s'", track, genome, hubUrl); struct jsonWrite *jw = apiStartOutput(); jsonWriteString(jw, "hubUrl", hubUrl); jsonWriteString(jw, "genome", genome); // jsonWriteString(jw, "track", track); unsigned chromSize = 0; struct bbiChromInfo *chromList = NULL; if (isNotEmpty(chrom)) { // jsonWriteString(jw, "chrom", chrom); chromSize = bbiChromSize(bbi, chrom); if (0 == chromSize) - apiErrAbort(400, "Bad Request", "can not find specified chrom=%s in bigBed file URL %s", chrom, bigDataUrl); + apiErrAbort(err400, err400Msg, "can not find specified chrom=%s in bigBed file URL %s", chrom, bigDataUrl); jsonWriteNumber(jw, "chromSize", (long long)chromSize); } else { chromList = bbiChromList(bbi); jsonWriteNumber(jw, "chromCount", (long long)slCount(chromList)); } unsigned uStart = 0; unsigned uEnd = chromSize; if ( ! (isEmpty(start) || isEmpty(end)) ) { uStart = sqlUnsigned(start); uEnd = sqlUnsigned(end); jsonWriteNumber(jw, "start", uStart); @@ -385,60 +385,60 @@ char *chrom = cgiOptionalString("chrom"); char *start = cgiOptionalString("start"); char *end = cgiOptionalString("end"); /* 'track' name in trackDb refers to a SQL 'table' */ char *track = cgiOptionalString("track"); char *sqlTable = cloneString(track); unsigned chromSize = 0; /* maybe set later */ unsigned uStart = 0; unsigned uEnd = chromSize; /* maybe set later */ if ( ! (isEmpty(start) || isEmpty(end)) ) { uStart = sqlUnsigned(start); uEnd = sqlUnsigned(end); if (uEnd < uStart) - apiErrAbort(400, "Bad Request", "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", uStart, uEnd); } if (isEmpty(db)) - apiErrAbort(400, "Bad Request", "missing URL variable db=<ucscDb> name for endpoint '/getData/track"); + apiErrAbort(err400, err400Msg, "missing URL variable db=<ucscDb> name for endpoint '/getData/track"); if (isEmpty(track)) - apiErrAbort(400, "Bad Request", "missing URL variable track=<trackName> name for endpoint '/getData/track"); + apiErrAbort(err400, err400Msg, "missing URL variable track=<trackName> name for endpoint '/getData/track"); struct trackDb *thisTrack = hTrackDbForTrackAndAncestors(db, track); if (NULL == thisTrack) - apiErrAbort(400, "Bad Request", "can not find track=%s name for endpoint '/getData/track", track); + apiErrAbort(err400, err400Msg, "can not find track=%s name for endpoint '/getData/track", track); /* might be a big* track with no table */ char *bigDataUrl = trackDbSetting(thisTrack, "bigDataUrl"); boolean tableTrack = TRUE; /* might have a specific table defined instead of the track name */ char *tableName = trackDbSetting(thisTrack, "table"); if (isNotEmpty(tableName)) { freeMem(sqlTable); sqlTable = cloneString(tableName); } struct sqlConnection *conn = hAllocConn(db); if (! sqlTableExists(conn, sqlTable)) { if (! bigDataUrl) - apiErrAbort(400, "Bad Request", "can not find specified 'track=%s' for endpoint: /getData/track?db=%s&track=%s", track, db, track); + apiErrAbort(err400, err400Msg, "can not find specified 'track=%s' for endpoint: /getData/track?db=%s;track=%s", track, db, track); else tableTrack = FALSE; } struct jsonWrite *jw = apiStartOutput(); jsonWriteString(jw, "db", db); if (tableTrack) { char *dataTime = sqlTableUpdate(conn, sqlTable); time_t dataTimeStamp = sqlDateToUnixTime(dataTime); replaceChar(dataTime, ' ', 'T'); /* ISO 8601 */ jsonWriteString(jw, "dataTime", dataTime); jsonWriteNumber(jw, "dataTimeStamp", (long long)dataTimeStamp); if (differentStringNullOk(sqlTable,track)) jsonWriteString(jw, "sqlTable", sqlTable); @@ -453,37 +453,37 @@ if (startsWith("big", thisTrack->type)) { if (bigDataUrl) bbi = bigFileOpen(thisTrack->type, bigDataUrl); else { char quickReturn[2048]; sqlSafef(query, sizeof(query), "select fileName from %s", sqlTable); if (sqlQuickQuery(conn, query, quickReturn, sizeof(quickReturn))) { bigDataUrl = cloneString(quickReturn); bbi = bigFileOpen(thisTrack->type, bigDataUrl); } } if (NULL == bbi) - apiErrAbort(400, "Bad Request", "failed to find bigDataUrl=%s for track=%s in database=%s for endpoint '/getData/track'", bigDataUrl, track, db); + apiErrAbort(err400, err400Msg, "failed to find bigDataUrl=%s for track=%s in database=%s for endpoint '/getData/track'", bigDataUrl, track, db); if (isNotEmpty(chrom)) { jsonWriteString(jw, "chrom", chrom); chromSize = bbiChromSize(bbi, chrom); if (0 == chromSize) - apiErrAbort(400, "Bad Request", "can not find specified chrom=%s in bigWig file URL %s", chrom, bigDataUrl); + apiErrAbort(err400, err400Msg, "can not find specified chrom=%s in bigWig file URL %s", chrom, bigDataUrl); if (uEnd < 1) uEnd = chromSize; jsonWriteNumber(jw, "chromSize", (long long)chromSize); } else { chromList = bbiChromList(bbi); jsonWriteNumber(jw, "chromCount", (long long)slCount(chromList)); } jsonWriteString(jw, "bigDataUrl", bigDataUrl); } /* when start, end given, show them */ if ( uEnd > uStart ) { @@ -523,141 +523,148 @@ apiFinishOutput(0, NULL, jw); hFreeConn(&conn); } static void getSequenceData(char *db, char *hubUrl) /* return DNA sequence, given at least a db=name and chrom=chr, optionally start and end, might be a track hub for UCSC database */ { char *chrom = cgiOptionalString("chrom"); char *start = cgiOptionalString("start"); char *end = cgiOptionalString("end"); if (isEmpty(chrom)) - apiErrAbort(400, "Bad Request", "missing URL chrom=<name> for endpoint '/getData/sequence?db=%s'", db); + apiErrAbort(err400, err400Msg, "missing URL chrom=<name> for endpoint '/getData/sequence?db=%s'", db); if (chromSeqFileExists(db, chrom)) { struct chromInfo *ci = hGetChromInfo(db, chrom); + unsigned chromSize = ci->size; struct dnaSeq *seq = NULL; if (isEmpty(start) || isEmpty(end)) + if (chromSize > MAX_DNA_LENGTH) + apiErrAbort(err400, err400Msg, "DNA sequence request %d too large, limit: %u for endpoint '/getData/sequence?db=%s;chrom=%s'", chromSize, MAX_DNA_LENGTH, db, chrom); + else seq = hChromSeqMixed(db, chrom, 0, 0); else + if ( (sqlSigned(end) - sqlSigned(start)) > MAX_DNA_LENGTH) + apiErrAbort(err400, err400Msg, "DNA sequence request %d too large, limit: %u for endpoint '/getData/sequence?db=%s;chrom=%s;start=%s;end=%s'", sqlSigned(end) - sqlSigned(start), MAX_DNA_LENGTH, db, chrom, start, end); + else seq = hChromSeqMixed(db, chrom, sqlSigned(start), sqlSigned(end)); if (NULL == seq) - apiErrAbort(400, "Bad Request", "can not find sequence for chrom=%s for endpoint '/getData/sequence?db=%s&chrom=%s'", chrom, db, chrom); + apiErrAbort(err400, err400Msg, "can not find sequence for chrom=%s for endpoint '/getData/sequence?db=%s;chrom=%s'", chrom, db, chrom); struct jsonWrite *jw = apiStartOutput(); if (isNotEmpty(hubUrl)) jsonWriteString(jw, "hubUrl", hubUrl); jsonWriteString(jw, "db", db); jsonWriteString(jw, "chrom", chrom); if (isEmpty(start) || isEmpty(end)) { jsonWriteNumber(jw, "start", (long long)0); jsonWriteNumber(jw, "end", (long long)ci->size); } else { jsonWriteNumber(jw, "start", (long long)sqlSigned(start)); jsonWriteNumber(jw, "end", (long long)sqlSigned(end)); } jsonWriteString(jw, "dna", seq->dna); apiFinishOutput(0, NULL, jw); freeDnaSeq(&seq); } else - apiErrAbort(400, "Bad Request", "can not find specified chrom=%s in sequence for endpoint '/getData/sequence?db=%s&chrom=%s", chrom, db, chrom); + apiErrAbort(err400, err400Msg, "can not find specified chrom=%s in sequence for endpoint '/getData/sequence?db=%s;chrom=%s", chrom, db, chrom); } /* static void getSequenceData(char *db, char *hubUrl) */ static void getHubSequenceData(char *hubUrl) /* return DNA sequence, given at least a genome=name and chrom=chr, optionally start and end */ { char *genome = cgiOptionalString("genome"); char *chrom = cgiOptionalString("chrom"); char *start = cgiOptionalString("start"); char *end = cgiOptionalString("end"); if (isEmpty(genome)) - apiErrAbort(400, "Bad Request", "missing genome=<name> for endpoint '/getData/sequence' given hubUrl='%s'", hubUrl); + apiErrAbort(err400, err400Msg, "missing genome=<name> for endpoint '/getData/sequence' given hubUrl='%s'", hubUrl); if (isEmpty(chrom)) - apiErrAbort(400, "Bad Request", "missing chrom=<name> for endpoint '/getData/sequence?genome=%s' given hubUrl='%s'", genome, hubUrl); + apiErrAbort(err400, err400Msg, "missing chrom=<name> for endpoint '/getData/sequence?genome=%s' given hubUrl='%s'", genome, hubUrl); struct trackHub *hub = errCatchTrackHubOpen(hubUrl); struct trackHubGenome *hubGenome = NULL; for (hubGenome = hub->genomeList; hubGenome; hubGenome = hubGenome->next) { if (sameString(genome, hubGenome->name)) break; } if (NULL == hubGenome) - apiErrAbort(400, "Bad Request", "failed to find specified genome=%s for endpoint '/getData/sequence' given hubUrl '%s'", genome, hubUrl); + apiErrAbort(err400, err400Msg, "failed to find specified genome=%s for endpoint '/getData/sequence' given hubUrl '%s'", genome, hubUrl); /* might be a UCSC database track hub, where hubGenome=name is the database */ if (isEmpty(hubGenome->twoBitPath)) { getSequenceData(hubGenome->name, hubUrl); return; } /* this MaybeChromInfo will open the twoBit file, if not already done */ struct chromInfo *ci = trackHubMaybeChromInfo(hubGenome->name, chrom); if (NULL == ci) - apiErrAbort(400, "Bad Request", "can not find sequence for chrom=%s for endpoint '/getData/sequence?genome=%s&chrom=%s' given hubUrl='%s'", chrom, genome, chrom, hubUrl); + apiErrAbort(err400, err400Msg, "can not find sequence for chrom=%s for endpoint '/getData/sequence?genome=%s;chrom=%s' given hubUrl='%s'", chrom, genome, chrom, hubUrl); struct jsonWrite *jw = apiStartOutput(); jsonWriteString(jw, "hubUrl", hubUrl); jsonWriteString(jw, "genome", genome); jsonWriteString(jw, "chrom", chrom); int fragStart = 0; int fragEnd = 0; if (isNotEmpty(start) && isNotEmpty(end)) { fragStart = sqlSigned(start); fragEnd = sqlSigned(end); jsonWriteNumber(jw, "start", (long long)fragStart); jsonWriteNumber(jw, "end", (long long)fragEnd); } else { jsonWriteNumber(jw, "start", (long long)0); jsonWriteNumber(jw, "end", (long long)ci->size); } struct dnaSeq *seq = twoBitReadSeqFrag(hubGenome->tbf, chrom, fragStart, fragEnd); if (NULL == seq) { if (fragEnd > fragStart) - apiErrAbort(400, "Bad Request", "can not find sequence for chrom=%s;start=%s;end=%s for endpoint '/getData/sequence?genome=%s&chrom=%s;start=%s;end=%s' give hubUrl='%s'", chrom, start, end, genome, chrom, start, end, hubUrl); + apiErrAbort(err400, err400Msg, "can not find sequence for chrom=%s;start=%s;end=%s for endpoint '/getData/sequence?genome=%s;chrom=%s;start=%s;end=%s' give hubUrl='%s'", chrom, start, end, genome, chrom, start, end, hubUrl); else - apiErrAbort(400, "Bad Request", "can not find sequence for chrom=%s for endpoint '/getData/sequence?genome=%s&chrom=%s' give hubUrl='%s'", chrom, genome, chrom, hubUrl); + apiErrAbort(err400, err400Msg, "can not find sequence for chrom=%s for endpoint '/getData/sequence?genome=%s;chrom=%s' give hubUrl='%s'", chrom, genome, chrom, hubUrl); } jsonWriteString(jw, "dna", seq->dna); apiFinishOutput(0, NULL, jw); } void apiGetData(char *words[MAX_PATH_INFO]) /* 'getData' function, words[1] is the subCommand */ { char *hubUrl = cgiOptionalString("hubUrl"); if (sameWord("track", words[1])) { if (isNotEmpty(hubUrl)) getHubTrackData(hubUrl); else getTrackData(); } else if (sameWord("sequence", words[1])) { if (isNotEmpty(hubUrl)) getHubSequenceData(hubUrl); else { char *db = cgiOptionalString("db"); if (isEmpty(db)) - apiErrAbort(400, "Bad Request", "missing URL db=<ucscDb> name for endpoint '/getData/sequence"); + apiErrAbort(err400, err400Msg, "missing URL db=<ucscDb> name for endpoint '/getData/sequence"); getSequenceData(db, NULL); } } else - apiErrAbort(400, "Bad Request", "do not recognize endpoint function: '/%s/%s'", words[0], words[1]); + apiErrAbort(err400, err400Msg, "do not recognize endpoint function: '/%s/%s'", words[0], words[1]); }