Expose dry-transaction failure step names


#1

I have a background job that calls a Transaction, which does a bit of work, decides what Transaction to call and calls it, then does some more work. A particular step in that innermost Transaction can fail, and I’d like the job to be able to handle that failure somehow. The problem is, as far as I can tell, there’s no way to pass that innermost StepFailure out, it always gets unwrapped into a normal Failure that doesn’t contain the step name, then wrapped in a StepFailure for the outer transaction step that called it.

class OuterTransaction
  include Dry::Transaction

  step :setup
  step :call_next
  step :handle_result

  def call_next(some_name, **kwargs)
    transaction = MyContainer::Transactions[some_name]
    transaction.call(**kwargs)
  end
end

class InnerTransactionA
  include Dry::Transaction

  step :setup
  check :validate
  try :dispatch, catch: [ApiClient::ClientError]
  step :cleanup

  def validate(credentials)
    credentials.key?(:token)
  end

  def dispatch_to_flakey_api(credentials)
    api_client.new(credentials).make_request(...)
  end
end

class SomeJob
  def perform
    OuterTransaction.new.call do |result|
      result.failure(:validate)  { |er| notify(...) }    # never gets called
      result.failure(:dispatch)  { |er| retry_job(...) } # never gets called
      result.failure(:call_next) { |er| ??? }            # This one gets called
      result.success { "yay" }
    end
  end
end

It’d be great if there was some way to get access to the step name from the inner transaction step that was the cause of the failure.