Reputation: 351
I'd like to run my existing fabfile tasks without the cli directly from Python. How do I catch 'execute' exceptions and capture the output for logging if any exceptions occur?
@roles(['localhost'])
def my_sudo_task():
sudo('ls -l /root/')
from fabfile import my_sudo_task
from fabric.tasks import execute
execute(my_sudo_task)
here is my exact problem:
try:
# is there a way to leave out stderr and capture it somehow?
with settings(hide('stdout', 'stderr', 'aborts', 'warnings', 'running')):
execute(my_sudo_task)
except Exception as e: # doesnt catch error
print ('ERROR')
raise
except:
print ('ERROR') # catches but lacks the error message that i can log
Upvotes: 0
Views: 986
Reputation: 11
The NetworkError and CommandTimeout exceptions are defined in the fabric.exceptions module. The execute() call returns a dictionary of whatever is returned by the task it executes with the hostnames as the keys. If an exception is encountered it will be stored in the dictionary as well. You can inspect the exception's 'message' attribute for a string description of the issue. See the following example:
>>> from fabric.api import run, execute
>>> from fabric.context_managers import quiet
>>> from fabric.state import env
>>> env.skip_bad_hosts = True
>>> env.warn_only = True
>>> def task_a():
... return run('pwd')
...
>>> with quiet():
... a = execute(task_a,hosts=['badhost'])
...
>>> a
{'badhost': NetworkError(Name lookup failed for badhost) => gaierror(8, 'nodename nor servname provided, or not known')}
>>> type(a['badhost'])
<class 'fabric.exceptions.NetworkError'>
>>> a['badhost'].message
'Name lookup failed for badhost'
Upvotes: 0
Reputation: 351
The following solved my issue
try:
with settings(hide('stdout', 'stderr', 'aborts', 'warnings', 'running')):
execute(my_sudo_task)
except SystemExit as e:
print (e.message)
because 'execute' doesn't technically throw an exception
issubclass(SystemExit, Exception) = False
Upvotes: 0
Reputation: 4137
You should handle errors by examining result codes inside the task. Exceptions aren't going to be descriptive enough.
from fabric.api import *
@roles(['localhost'])
def my_sudo_task():
with settings(warn_only=True):
result = sudo('ls -l /root/')
if result.return_code == 0:
[do something...]
elif result.return_code == 1:
[do something...]
else:
[do something else...]
from fabfile import my_sudo_task
from fabric.tasks import execute
execute(my_sudo_task)
See the tutorial section on failure handling.
Upvotes: 1