import contextlib
@contextlib.contextmanager
def error_processor(uniq_error_in='_uniq'):
sp = savepoint()
try:
yield
except DatabaseError as e:
if uniq_error_in not in e.args[0]:
raise
savepoint_rollback(sp)
else:
savepoint_commit(sp)
This is a context manager that should do the job your coroutine does, but hopefully in a more understandable manner. You'd use it as follows:
with commit_on_success():
for provider_name, booking_data in offer.booking_data.iteritems():
with error_processor():
BookingData.objects.create(
offer=pnr_offer, provider=provider_name, **booking_data)
I couldn't fit the commit_on_success
into the context manager, as the commit_on_success
needs to go around the for
loop, but the error handling needs to go inside the loop.