Reputation: 7275
I have a script that loops through a few file paths in order execute some other python and bash scripts using subprocess.
I know that these scripts will occasionally fail, and I want to catch the exception and stop the loop/exit the calling script. This seems like it should be very simple – but I'm going nuts getting it to work.
I've tried a number of subprocess methods, and I can't seem to catch a CalledProcessError from any of them (call
, check_call
, check_output
Popen
).
# calling.py
for script in ['w', 'x', 'y']:
try:
subprocess.check_output('ipython {}.py'.format(script).split())
except subprocess.CalledProcessError as e:
print "Caught CalledProcessError"
raise
except Exception as e:
print "Caught some other exception"
raise
Now imagine the first script throws an exception. I want it to cause the calling script to exit.
# w.py
print "w"
a = {}
a[0] # KeyError
Instead none of the exceptions are caught by the calling script and the calling script continues the loop.
$ ipython calling.py
w
---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
/Users/h138124/git/exceptional/w.py in <module>()
1 print "w"
2 a = {}
----> 3 a[0]
KeyError: 0
x
y
Upvotes: 2
Views: 1561
Reputation: 301
I had exactly the same issue and started debugging into subprocess.py.
Than I realized that I never reached a breakpoint in the subprocess.run() function.
And than it came to my mind, that I did install the subprocess.run package for python35 a time ago.
After deleting the package it worked again.
Upvotes: 2
Reputation: 4160
Funnily enough I wanted to do exactly what is happening to you, and I could not, because I was not using try except (I am in python 2.7). What happen if you simply do that?
for script in ['w', 'x', 'y']:
out = subprocess.check_output('ipython {}.py'.format(script).split())
print(out)
As far as I can understand of this mysterious subprocess, if you want the program to stop you have to disentangle from the try except structure, as subprocess.check_output will stop by default when the exit status is 1.
Upvotes: 0
Reputation: 36023
Looks like ipython
doesn't return a non-zero exit code on exceptions, which is required for subprocess.check_output
to raise a CalledProcessError
. Just use python
.
$ cat test.py
1/0
$ python test.py
Traceback (most recent call last):
File "test.py", line 1, in <module>
1/0
ZeroDivisionError: integer division or modulo by zero
$ echo $?
1
$ ipython test.py
---------------------------------------------------------------------------
ZeroDivisionError Traceback (most recent call last)
/Users/alexhall/Dropbox/python/sandbox/test.py in <module>()
----> 1 1/0
ZeroDivisionError: integer division or modulo by zero
$ echo $?
0
Alternatively, just import the script or use execfile
or something similar.
Upvotes: 0