scientist
scientist copied to clipboard
Ignoring specific exceptions
Currently observation values and not observation objects are being passed to ignore. This means it's not possible to ignore transient exceptions that occur in either candidate or control. When an exception occurs, nil is passed as value to ignore for that behavior.
Example:
e = Scientist::Experiment.new "foo"
e.use { rand > 0.001 ? 42 : raise SomeConnectionTimedOut.new }
e.try { rand > 0.001 ? 42 : raise SomeConnectionTimedOut.new }
e.ignore do |control, candidate|
# control/candidate is nil if exception occurred in that behavior
end
It would be great if ignore received an observation object instead of only the observation value. That would allow examining the exception value.
Example:
# Proposed behavior! This is currently not possible.
ignore do |control, candidate|
control.exception.is_a?(SomeConnectionTimedOut) ||
candidate.exception.is_a?(SomeConnectionTimedOut)
end
I currently work around the above issue by rescuing inside try/use and return a sentinel value -- it's a terrible hack though. Would you accept a PR implementing this?
@andreas :wave: Doing some long-delayed issue gardening. I like this idea, but I'm wondering how to implement it in a backwards-compatible way. We might need to do this w/a major version bump, although even there I'm reluctant to break the interface without a deprecation period.
Ideas for backwards-compatible solutions (none of them particularly clean):
ignorecould pass more arguments to the block, which is backwards-compatible assuming clients use a proc.- Add a new method
ignore2which receives observation objects instead of values. - Pass a custom
nil-value as observation value toignoreif an exception is raised. This specialnil-value should expose the exception.