The programs shown below are meant to demonstrate a very simple way of accomplishing your goal.
A.py
The entire purpose of program A is to keep running program B over and over again. The shell argument is specified in this example so that it will easily run on both Windows and Linux, assuming program B has permission to execute. Feel free to expand on this program as you have need to.
#! /usr/bin/env python3
import subprocess
def main():
while True:
subprocess.run('B.py', shell=True)
if __name__ == '__main__':
main()
B.py
This program should be replaced with your own, but it demonstrates a running program that crashes with random exceptions. The EXCEPTIONS strings is copied straight from the documentation, and the rest of the code should be easy to follow. The only use for this program is for testing program A.
#! /usr/bin/env python3
import builtins
import random
import time
EXCEPTIONS = '''\
BaseException
+-- SystemExit
+-- KeyboardInterrupt
+-- GeneratorExit
+-- Exception
+-- StopIteration
+-- StopAsyncIteration
+-- ArithmeticError
| +-- FloatingPointError
| +-- OverflowError
| +-- ZeroDivisionError
+-- AssertionError
+-- AttributeError
+-- BufferError
+-- EOFError
+-- ImportError
+-- ModuleNotFoundError
+-- LookupError
| +-- IndexError
| +-- KeyError
+-- MemoryError
+-- NameError
| +-- UnboundLocalError
+-- OSError
| +-- BlockingIOError
| +-- ChildProcessError
| +-- ConnectionError
| | +-- BrokenPipeError
| | +-- ConnectionAbortedError
| | +-- ConnectionRefusedError
| | +-- ConnectionResetError
| +-- FileExistsError
| +-- FileNotFoundError
| +-- InterruptedError
| +-- IsADirectoryError
| +-- NotADirectoryError
| +-- PermissionError
| +-- ProcessLookupError
| +-- TimeoutError
+-- ReferenceError
+-- RuntimeError
| +-- NotImplementedError
| +-- RecursionError
+-- SyntaxError
| +-- IndentationError
| +-- TabError
+-- SystemError
+-- TypeError
+-- ValueError
| +-- UnicodeError
| +-- UnicodeDecodeError
| +-- UnicodeEncodeError
| +-- UnicodeTranslateError
+-- Warning
+-- DeprecationWarning
+-- PendingDeprecationWarning
+-- RuntimeWarning
+-- SyntaxWarning
+-- UserWarning
+-- FutureWarning
+-- ImportWarning
+-- UnicodeWarning
+-- BytesWarning
+-- ResourceWarning
'''
def main():
time.sleep(random.uniform(1, 9))
lines = EXCEPTIONS.splitlines()
names = [line.rsplit(None, 1)[-1] for line in lines]
raise getattr(builtins, random.choice(names))()
if __name__ == '__main__':
main()