Вам нужно было бы перехватывать любые исключения из потоков в самом потоке. Затем вы можете как-то передать этот результат обратно в основной поток. Вот минимальный пример, который использует объект общего флага, чтобы указать, что поток потерпел крах. Затем основной цикл может просто подождать, пока этот флаг не изменится.
import threading
import time
class Flag:
ended = False
def asserter(flag):
time.sleep(3)
try:
assert False
except AssertionError:
flag.ended = True
thread = threading.Thread(target=asserter, args=(Flag,))
thread.start()
while not Flag.ended:
print('Main')
time.sleep(1)
print('done')