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;