Can I catch error codes when using Fabric to run() calls in a remote shell?
Solution 1:
You can prevent aborting on non-zero exit codes by using the settings
context manager and the warn_only
setting:
from fabric.api import settings
with settings(warn_only=True):
result = run('pngout old.png new.png')
if result.return_code == 0:
do something
elif result.return_code == 2:
do something else
else: #print error to user
print result
raise SystemExit()
Update: My answer is outdated. See comments below.
Solution 2:
Yes, you can. Just change the environment's abort_exception
. For example:
from fabric.api import settings
class FabricException(Exception):
pass
with settings(abort_exception = FabricException):
try:
run(<something that might fail>)
except FabricException:
<handle the exception>
The documentation on abort_exception
is here.
Solution 3:
Apparently messing with the environment is the answer.
fabric.api.settings
can be used as a context manager (with with
) to apply it to individual statements. The return value of run()
, local()
and sudo()
calls isn't just the output of the shell command, but also has special properties (return_code
and failed
) that allow reacting to the errors.
I guess I was looking for something closer to the behaviour of subprocess.Popen
or Python's usual exception handling.
Solution 4:
try this
from fabric.api import run, env
env.warn_only = True # if you want to ignore exceptions and handle them yurself
command = "your command"
x = run(command, capture=True) # run or local or sudo
if(x.stderr != ""):
error = "On %s: %s" %(command, x.stderr)
print error
print x.return_code # which may be 1 or 2
# do what you want or
raise Exception(error) #optional
else:
print "the output of %s is: %s" %(command, x)
print x.return_code # which is 0