Author: Aaron M. Ucko
Last-Update: 2021-04-09 18:03:05 -0400
Description: Enhance detection of bad versions of tblastn

--- a/kaptive.py
+++ b/kaptive.py
@@ -49,6 +49,7 @@ import fcntl
 import gzip
 import copy
 import random
+import re
 from collections import OrderedDict
 from Bio import SeqIO
 
@@ -904,22 +905,27 @@ def get_blast_hits(database, query, thre
     out, err = process.communicate()
     out = convert_bytes_to_str(out)
     err = convert_bytes_to_str(err)
-    if err:
-        quit_with_error(command[0] + ' encountered an error:\n' + err)
-    if process.returncode != 0:
+    if err or process.returncode != 0:
         msg = command[0] + ' crashed!\n'
 
         # A known crash can occur with tblastn and recent versions of BLAST+ when multiple threads
         # are used. Check for this case and display an informative error message if so.
         version = get_blast_version(command[0])
-        bad_version = (version == '2.4.0') or (version == '2.5.0') or (version == '2.6.0')
-        if threads > 1 and bad_version:
+        bad_version = re.match(r'2\.(?:[4-9]|1[01])\.\d+$', version)
+        if threads > 1 and bad_version \
+           and (not err or err.startswith("terminate called ")):
             msg += '\nYou are using BLAST+ v' + version + ' which may crash when running with '
             msg += 'multiple threads.\n\n'
             msg += 'To avoid this issue, try one of the following:\n'
             msg += '  1) Use an unaffected version of BLAST+ (v2.3.0 or earlier should work)\n'
             msg += '  2) Run Kaptive with "--threads 1" (will probably be slower)\n'
-        quit_with_error(msg)
+            if err:
+                msg += "\nRaw error:\n" + err
+            quit_with_error(msg)
+        elif err:
+            quit_with_error(command[0] + ' encountered an error:\n' + err)
+        else:
+            quit_with_error(msg)
 
     if genes:
         blast_hits = [GeneBlastHit(line) for line in line_iterator(out)]
