I'm trying to handle failure on fabric, but the example I saw on the docs was too localized for my taste. I need to execute rollback actions if any of a number of actions fail. I tried, then, to use contexts to handle it, like this:
@_contextmanager
def failwrapper():
with settings(warn_only=True):
result = yield
if result.failed:
rollback()
abort("********* Failed to execute deploy! *********")
And then
@task
def deploy():
with failwrapper():
updateCode()
migrateDb()
restartServer()
Unfortunately, when one of these tasks fail, I do not get anything on result.
Is there any way of accomplishing this? Or is there another way of handling such situations?
According to my tests, you can accomplish that with this:
from contextlib import contextmanager
@contextmanager
def failwrapper():
try:
yield
except SystemExit:
rollback()
abort("********* Failed to execute deploy! *********")
As you can see I got rid of the warn_only setting as I suppose you don't need it if the rollback can be executed and you're aborting the execution anyway with abort().
Fabric raises SystemExit exception when encountering errors and warn_only setting is not used. We can just catch the exception and do the rollback.
Following on from Henri's answer, this also handles keyboard interrupts (Ctrl-C) and other exceptions:
@_contextmanager
def failwrapper():
try:
yield
except:
rollback()
raise
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With