Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

around steps and Dry::Transaction::Operation don't get along #114

Open
dmaze opened this issue Nov 14, 2018 · 1 comment
Open

around steps and Dry::Transaction::Operation don't get along #114

dmaze opened this issue Nov 14, 2018 · 1 comment

Comments

@dmaze
Copy link

dmaze commented Nov 14, 2018

I've gotten into the habit of writing dry-transaction operations as individual classes that include Dry::Transaction::Operation. (It avoids the scary 5-letter "m" word.) If you use this in an operation class that's intended to be an around step, like so:

class First
  include Dry::Transaction::Operation
  def call(input)
    yield Success(input + 1)
  end
end

You will get a backtrace when you run it. https://gist.github.com/dmaze/ea78510a8870089be510a55d8fb38a8e is a more complete reproduction script. Running that prints out:

first 1
done with first
LocalJumpError: yield called out of block
              call at ./dry-transaction-operation.rb:20
     block in call at .../gems/dry-matcher-0.7.0/lib/dry/matcher.rb:35
              call at org/jruby/RubyMethod.java:129
              call at .../gems/dry-transaction-0.13.0/lib/dry/transaction/callable.rb:33
              call at .../gems/dry-transaction-0.13.0/lib/dry/transaction/step_adapters/around.rb:12
              call at org/jruby/RubyMethod.java:129
              call at .../gems/dry-transaction-0.13.0/lib/dry/transaction/step_adapter.rb:41
     block in call at .../gems/dry-transaction-0.13.0/lib/dry/transaction/step.rb:52
    with_broadcast at .../gems/dry-transaction-0.13.0/lib/dry/transaction/step.rb:61
              call at .../gems/dry-transaction-0.13.0/lib/dry/transaction/step.rb:52
  block in compile at .../gems/dry-transaction-0.13.0/lib/dry/transaction/stack.rb:19
              bind at .../gems/dry-monads-0.4.0/lib/dry/monads/right_biased.rb:48
  block in compile at .../gems/dry-transaction-0.13.0/lib/dry/transaction/stack.rb:19
              call at .../gems/dry-transaction-0.13.0/lib/dry/transaction/stack.rb:12
              call at .../gems/dry-transaction-0.13.0/lib/dry/transaction/instance_methods.rb:28
            <main> at ./dry-transaction-operation.rb:46

More specifically, it looks like the Operation mixin wraps #call in a dry-matcher, and the generated method doesn't pass the block up to the user code (it looks like it might repurpose it for something else).

An easy enough workaround is to include Dry::Monads::Result::Mixin instead.

I'm running this with jruby-9.2.0.0 and the gem versions shown in the backtrace, should that turn out to matter.

@TastyPi
Copy link

TastyPi commented Jun 15, 2023

I found a workaround - dry-transaction doesn't actually care that the object includes Dry::Transaction::Operation specifically, it just uses the call method. So you can instead replace it with Dry::Monads[:result] directly:

class First
  include Dry::Monads[:result]
  def call(input)
    yield Success(input + 1)
  end
end

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants