I am almost sure you can achieve the same goal with a rescue clause.
Your communicator class should not be responsible for updating the record1 in case of failures, that's your app logic.
defcallrecord1# get record1 somehowActiveRecord::Base.transactiondorecord1.update!(some_data)external_service_response=Communicator.call!(record1)# raises exception if response is not a successrecord2.update!(external_service_response)endrescueSpecificCommunicatorError=>error# save error can be a flag passed to this methodrecord1.update(external_service_error_response)ifsave_error==trueraise# without any arguments will raise the last errorend
Hmm no, the error raised inside the transaction block will force the transaction to rollback, but ActiveRecord will re-raise the same error, here I'm rescuing after the rollback has occurred, then re-raising again. If you don't need to re-raise the error again you can simply omit it.
I am almost sure you can achieve the same goal with a rescue clause.
Your communicator class should not be responsible for updating the record1 in case of failures, that's your app logic.
hmm, will the exception raised outside the transaction block cause the transaction to roll back?
Hmm no, the error raised inside the transaction block will force the transaction to rollback, but ActiveRecord will re-raise the same error, here I'm rescuing after the rollback has occurred, then re-raising again. If you don't need to re-raise the error again you can simply omit it.
api.rubyonrails.org/classes/Active...
that is a great solution. I don't know why I haven't thought of that :D Thank you so much, Edgar!