0

I am making a python program (A) that runs another file (B). If B exits with code 0, A exits too. However, if B crashes, i want to handle that exception myself in A.

There is this question that asks the same thing, however, the one asking only needs the exit code or the error message printed to stderr. However, i want the raw data otherwise provided by sys.exc_info if the exception occured in the parent / main file (A).

j307
  • 108
  • 1
  • 7
  • Have you considered using the [subprocess](https://docs.python.org/3/library/subprocess.html) module? – alfinkel24 Aug 02 '21 at 21:50
  • @alfinkel24 I want to, but python handles the exception itself rather than A doing it. So therefore i can't handle the exception in A. If there is any way to handle exceptions in A using subprocess, please tell me, I've only tried subproces.run("python", B) – j307 Aug 03 '21 at 09:52
  • Have you tried it with the `check=True` option? From the documentation: `If check is true, and the process exits with a non-zero exit code, a CalledProcessError exception will be raised. Attributes of that exception hold the arguments, the exit code, and stdout and stderr if they were captured.`. As in `subprocess.run("python", B, check=True)`. – alfinkel24 Aug 03 '21 at 13:13
  • @alfinkel24 It works, thank you. Python still prints the stacktrace tho, is there any way to stop that too? I want to print it myself. – j307 Aug 04 '21 at 11:53
  • You can redirect STDERR to /dev/null in B.py. ref: the accepted answer for https://stackoverflow.com/questions/6735917/redirecting-stdout-to-nothing-in-python but instead of sys.stdout you'd set sys.stderr. – alfinkel24 Aug 04 '21 at 12:58
  • Answer updated below – alfinkel24 Aug 04 '21 at 13:09

1 Answers1

0

Try subprocess with the check=True option:

From the subprocess docs:

If check is true, and the process exits with a non-zero exit code, a 
CalledProcessError exception will be raised. Attributes of that 
exception hold the arguments, the exit code, and stdout and stderr if 
they were captured.

If B.py is something like:

print("HELLO from B")
raise Exception("MEH")

Then A.py could be something like:

import subprocess

try:
    print("TRYING B.py")
    subprocess.run(["python", "B.py"], check=True)
except subprocess.CalledProcessError as cpe:
    print("OH WELL: Handling exception from B.py")
    print(f"Exception from B: {cpe}")

The result:

~ > python A.py
TRYING B.py
HELLO from B
Traceback (most recent call last):
  File "B.py", line 2, in <module>
    raise Exception("MEH")
Exception: MEH
OH WELL: Handling exception from B.py
Exception from B: Command '['python', 'B.py']' returned non-zero exit status 1.

To silence the exception from display, change B.py to the following:

import os
import sys
sys.stderr = open(os.devnull, 'w')
print("HELLO from B")
raise Exception("MEH")

The result:

~ > python A.py
TRYING B.py
HELLO from B
OH WELL: Handling exception from B.py
Exception from B: Command '['python', 'B.py']' returned non-zero exit status 1.
alfinkel24
  • 551
  • 5
  • 13