e020a087201d536e5ffe573fa6fb1ad1be68127c angie Wed Dec 18 16:54:56 2013 -0800 In MLQ #12367, the user got a blank screen when trying to view a CTusing a Mac-mangled BAM file. Of course we need to show an error message instead of SEGV/blank screen; but hgCustom also shouldn't have accepted the file as a custom track. It turns out that the samtools lib function samopen() may return a non-null file handler with a null header, when the header is invalid. So we need to check not only for null result from samopen, but also null header inside non-null result. Meanwhile, I noticed that hgCustom's error reporting was actually masking more detailed error messages from lib code, because of its use of errCatch around bamFileExists. errCatch only lets errAbort messages propagate, not warnings; bamFileExists has a warn() that is lost in transmission. I added bamFileAndIndexMustExist which uses errAbort so that errCatch in callers will get the more informative error instead of having to make up one of its own. trackHub checking code also needed this stronger form of checking. I also moved some duplicated (or triplicated) code in bamFile.c into functions. refs #12367 diff --git src/hg/lib/trackHub.c src/hg/lib/trackHub.c index 18a5606..3bd17fd 100644 --- src/hg/lib/trackHub.c +++ src/hg/lib/trackHub.c @@ -830,32 +830,31 @@ /* Just open and close to verify file exists and is correct type. */ struct bbiFile *bbi = bigBedFileOpen(bigDataUrl); bbiFileClose(&bbi); } else if (startsWithWord("vcfTabix", type)) { /* Just open and close to verify file exists and is correct type. */ struct vcfFile *vcf = vcfFileMayOpen(bigDataUrl, 1, 1, FALSE); if (vcf == NULL) errAbort("%s is not a VCF file", bigDataUrl); vcfFileFree(&vcf); } else if (startsWithWord("bam", type)) { - /* For bam files, the following call checks both main file and index. */ - bamFileExists(bigDataUrl); + bamFileAndIndexMustExist(bigDataUrl); } else errAbort("unrecognized type %s in genome %s track %s", type, genome->name, tdb->track); freez(&bigDataUrl); } errCatchEnd(errCatch); if (errCatch->gotError) { retVal = 1; dyStringPrintf(errors, "%s", errCatch->message->string); } errCatchFree(&errCatch); } return retVal;