-
Notifications
You must be signed in to change notification settings - Fork 142
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
compose does not copy symbolic errors #87
Comments
This might not make sense. When And we can't copy symbolic errors over to arbitrary attributes because they might not exist on the receiver. I don't have a good solution for this yet. |
Here's how this currently behaves: class A < ActiveInteraction::Base
integer :x, :y
def execute; end
end
class B < ActiveInteraction::Base
boolean :x
def execute
compose(A, inputs)
end
end
errors = B.run(x: true).errors
errors.messages
# => {:base=>["X is not a valid integer", "Y is required"]}
errors.symbolic
# => {} I think ideally it should behave like this: errors.messages
# => {:base=>["Y is required"], :x=>["is not a valid integer"]}
errors.symbolic
# => {:x=>[:invalid_type]} Do you agree? |
What do we gain with this change? Does this improve testing by attaching the error to the appropriate input? |
@tfausak I agree I have the following use case:
The invoicing service validates the tax identification number (in Poland it's called NIP). I have a But when I composed the The way I add the error is following: self.errors.add err[0].downcase.to_sym, :invalid
Is this there another way to add errors during execution, that will pass them on the the caller? Best regards, Szymon. |
@Szeliga thanks for providing a real world use case! There's currently no other built in way to transfer errors as part of composition. If you want to do it yourself, that's always possible (but a little verbose). For instance: class A < ActiveInteraction::Base
def execute; end
end
class B < ActiveInteraction::Base
def execute
outcome = A.run(...)
if outcome.invalid?
# Do something with outcome.errors (both messages and symbolic).
return
end
# ...
end
end I've started a pull request (#194) to discuss a possible solution to this problem. |
Ah, of course. Thanks for the tip. I forgot, I can acces the errors this way. Sometimes I expect too much magic from libraries :) |
This is the last remaining issue on the v2.0.0 milestone. I'm not sure that #216 the best solution, but it's a solution. And I think it's better than the way it is now. |
I want to resurrect this issue for more discussion. I encountered a use case where this behavior would have been extremely useful. Let's say you want to refactor an interaction. It will accept the same inputs and (hopefully) return the same result, but the internals will be different. One way to accomplish this would be to create a new interaction for the refactored version and run it side-by-side with the original version. (Gems like dat-science help with this part.) Since the two interactions have the same inputs, you should be able to call either of them from a top-level interaction and the errors should end up in the right place. More concretely: class Addition < ActiveInteraction::Base
integer :x, :y
def execute
Science::Experiment.new('Addition') do |e|
e.control { compose(AdditionControl) }
e.candidate { compose(AdditionCandidate) }
end.run
end
end
class AdditionControl < ActiveInteraction::Base
import_filters Addition
def execute
x + y
end
end
class AdditionCandidate < ActiveInteraction::Base
import_filters Addition
def execute
x - (-y)
end
end It looks like everything should Just Work™, but the resulting errors leave a lot to be desired. errors = Addition.run(x: 1, y: 'oops').errors
errors.messages
# => {:base=>["Y is not a valid integer"]}
errors.symbolic
# => {} |
I'm taking this off the v2.0.0 milestone, but it's still something that we might want to do. |
I am adding this to the v3.0.0 milestone. We either need to make a decision about it and fix it, or close it and commit to keeping things the way they are. |
When using
compose
with an interaction that usesadd_sym
to create symbolic errors, thecompose
method doesn't pass these symbolic errors along to the outcome.The text was updated successfully, but these errors were encountered: