Reputation:
I am trying to find a way to handle Fabric errors.
Example: if my remote host goes down for maintenance, and my application is running, trying to have some work done on it, I get an exception from Fabric. This block my app, and print a horrible stack trace.
To avoid this, since I need to know when a host is down, I am wrapping my requests to remote, with a try block, but I am not sure what should I put in the except block, to catch only the exceptions coming from Fabric (like the networkError and similar).
Which is the correct way to handle a try-except block with Fabric? Or to be more specific, what do I put in the "except" block, so it will catch any exception coming from fabric, and avoid to have the whole application to quit and print out the stack error?
Upvotes: 3
Views: 4103
Reputation: 180401
logging.exception
will output the traceback after you catch the error:
import logging
try:
1/0
except Exception as e:
logging.exception(e)
ERROR:root:division by zero
Traceback (most recent call last):
File "/home/padraic/Dropbox/python/py3/size.py", line 105, in <module>
1/0
ZeroDivisionError: division by zero
Process finished with exit code 0
If you look at the failure-handling in the docs you will see you can use a context manager to only warn when you get a non zero exit status.
Once the task list has been constructed, Fabric will start executing them as outlined in Execution strategy, until all tasks have been run on the entirety of their host lists. However, Fabric defaults to a “fail-fast” behavior pattern: if anything goes wrong, such as a remote program returning a nonzero return value or your fabfile’s Python code encountering an exception, execution will halt immediately.
This is typically the desired behavior, but there are many exceptions to the rule, so Fabric provides env.warn_only, a Boolean setting. It defaults to False, meaning an error condition will result in the program aborting immediately. However, if env.warn_only is set to True at the time of failure – with, say, the settings context manager – Fabric will emit a warning message but continue executing.
from fabric.api import settings
with settings(warn_only=True):
p = run('sudo foo')
if p.return_code == 0:
...
elif p.return_code == 1:
....
There is also an env.abort_exception:
Default: None
Fabric normally handles aborting by printing an error message to stderr and calling sys.exit(1). This setting allows you to override that behavior (which is what happens when env.abort_exception is None.)
Give it a callable which takes a string (the error message that would have been printed) and returns an exception instance. That exception object is then raised instead of SystemExit (which is what sys.exit does.)
Much of the time you’ll want to simply set this to an exception class, as those fit the above description perfectly (callable, take a string, return an exception instance.) E.g. env.abort_exception = MyExceptionClass.
Upvotes: 4
Reputation: 5805
so you want to know when this happens in some way? how about catching this exception (with the exact set of exceptions that could cause this, don't try to catch too much) and have it email you or something similar and reraise the same exception so you know what happened.
Edit. It is easy to not have the traceback display on the screen, but Im not sure I recommend avoiding the traceback completely. Implementing logging is good alternative, or formatting the traceback to what you want is also acceptable. Look at the traceback module https://docs.python.org/2/library/traceback.html
Upvotes: 1