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