Skip to content

Commit 7d9954c

Browse files
committed
Rescue can call :instance_method for old and new signature.
1 parent d6891d7 commit 7d9954c

File tree

2 files changed

+35
-30
lines changed

2 files changed

+35
-30
lines changed

lib/trailblazer/macro/rescue.rb

Lines changed: 27 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -7,27 +7,25 @@ def self.Rescue(*exceptions, handler: NoopHandler, id: Macro.id_for(nil, macro:
77

88
# In Rescue(), for whatever reason we support a circuit interface handler
99
# where we ignore the result set?
10-
# handler = Trailblazer::Activity::Circuit.Step(handler)
1110

1211
is_instance_method = false
1312
handler = Activity::Option.build(handler) do |instance_method|
1413
# this is for :instance_methods
1514
is_instance_method = true
16-
callable = Rescue::InstanceMethodWithCircuitInterfaceAndKwargs.new(instance_method)
1715

1816
# assuming we have to deprecate everything.
19-
Rescue::Deprecate::InstanceMethodAtRuntime.new(callable, instance_method) # TODO: remove in 2.3.
17+
Rescue::Deprecate::InstanceMethodAtRuntime.new(nil, instance_method)
2018
end
2119

2220
if is_instance_method
2321
# deprecate at runtime :D
2422
else
25-
# deprecate now!
26-
if handler.method(:call).arity == -3
27-
# raise handler.inspect
28-
puts "@@@@@ xxx #{handler.inspect}"
23+
# This only catches the documented signature:
24+
# def(exception, (ctx), *)
25+
if Rescue::Deprecate.old_signature?(handler.method(:call))
2926
Rescue::Deprecate.warning_for_deprecated_callable
30-
# raise "why are we not hitting this from line 291?"
27+
28+
# deprecate now!
3129
handler = Rescue::Deprecate::Callable.new(handler)
3230
end
3331
end
@@ -59,21 +57,38 @@ def self.Rescue(*exceptions, handler: NoopHandler, id: Macro.id_for(nil, macro:
5957

6058
module Rescue
6159
module Deprecate
60+
def self.old_signature?(method)
61+
# this doesn't catch all, but we ignore that.
62+
method.arity == -3 && method.parameters[1] == [:req] # (ctx)
63+
end
64+
65+
# This is kind of specific to Rescue, but might be useful elsewhere. We want to run a circuit interface
66+
# *instance method* with keyword arguments. in a normal CI-conform callable, this doesn't need any
67+
# wrapping, but instance_methods are different.
68+
# TODO: this is not Deprecate specific!!!!!!!!!!!!!!!!!!!!
69+
def self.translate_from_circuit_interface_to_instance_method_option(instance_method_option, ctx, flow_options, circuit_options, **kwargs)
70+
instance_method_option.(ctx, flow_options, circuit_options, keyword_arguments: kwargs, **circuit_options)
71+
end
72+
6273
class InstanceMethodAtRuntime < Struct.new(:filter, :instance_method_option)
6374
def call(ctx, flow_options, circuit_options, exception:)
64-
exec_context = circuit_options.fetch(:exec_context)
75+
# Try to retrieve the method instance of the handler method.
6576
# hacky, but hey, it's deprecation code!
77+
exec_context = circuit_options.fetch(:exec_context)
6678
instance_method = exec_context.method(instance_method_option.instance_variable_get(:@filter))
6779

68-
if instance_method.arity == -3 # this doesn't catch all, but we ignore that.
80+
if Deprecate.old_signature?(instance_method)
6981
# Activity::Deprecate.warn(
7082
# Activity::DSL::Linear::Deprecate.dsl_caller_location(after: /forwardable.+Rescue/),
7183
warning = "#{exec_context.class}##{instance_method.name} " + Deprecate.message_for_deprecation_warning
7284

7385
Kernel.warn %([Trailblazer] #{warning}\n) # TODO: allow that in Activity::Deprecate.
86+
87+
# this is a bit hacky but we can call old signature with the "correct" arguments.
88+
return Deprecate.translate_from_circuit_interface_to_instance_method_option(instance_method_option, exception, [ctx, flow_options], circuit_options)
7489
end
7590

76-
filter.(ctx, flow_options, circuit_options, exception: exception)
91+
Deprecate.translate_from_circuit_interface_to_instance_method_option(instance_method_option, ctx, flow_options, circuit_options, exception: exception)
7792
end
7893
end
7994

@@ -95,17 +110,7 @@ def self.warning_for_deprecated_callable
95110
message_for_deprecation_warning
96111
)
97112
end
98-
end
99-
# This is kind of specific to Rescue, but might be useful elsewhere. We want to run a circuit interface
100-
# *instance method* with keyword arguments. in a normal CI-conform callable, this doesn't need any
101-
# wrapping, but instance_methods are different.
102-
class InstanceMethodWithCircuitInterfaceAndKwargs < Struct.new(:instance_method_option) # DISCUSS: move somewhere else?
103-
def call(ctx, flow_options, circuit_options, exception:, **kwargs)
104-
# Call the method the old, weird style with exception as a positional argument
105-
# followed by the composite circuit interface.
106-
instance_method_option.(exception, [ctx, flow_options], keyword_arguments: kwargs, **circuit_options)
107-
end
108-
end
113+
end # Deprecate
109114
end
110115
end
111116
end

test/docs/rescue_test.rb

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,11 @@ class NestedInsanity < Trailblazer::Operation
1313
step :a
1414
step Rescue {
1515
step :y
16-
pass ->(options, **) { raise Y if options["raise-y"] }
16+
pass ->(ctx, **) { raise Y if ctx["raise-y"] }
1717
step :z
1818
}
1919
step :b
20-
pass ->(options, **) { raise A if options["raise-a"] }
20+
pass ->(ctx, **) { raise A if ctx["raise-a"] }
2121
step :c
2222
left :inner_err
2323
}
@@ -79,7 +79,7 @@ module Song::Activity; end
7979

8080
#:rescue-handler
8181
class MyHandler
82-
def self.call(exception, (ctx), *)
82+
def self.call(ctx, flow_options, circuit_options, exception:)
8383
ctx[:exception_class] = exception.class
8484
end
8585
end
@@ -115,7 +115,7 @@ class RescueWithModuleHandlerTest < Minitest::Spec
115115
Memo = Class.new
116116

117117
module MyHandler
118-
def self.call(exception, (ctx), *)
118+
def self.call(ctx, *, exception:)
119119
ctx[:exception_class] = exception.class
120120
end
121121
end
@@ -145,7 +145,7 @@ class RescueWithMethodHandlerTest < Minitest::Spec
145145
#:rescue-method
146146
class Memo::Create < Trailblazer::Operation
147147
step :find_model
148-
step Rescue( RuntimeError, handler: :my_handler ) {
148+
step Rescue(RuntimeError, handler: :my_handler) {
149149
step :update
150150
step :rehash
151151
}
@@ -156,7 +156,7 @@ class Memo::Create < Trailblazer::Operation
156156
include Rehash
157157
#~methods end
158158

159-
def my_handler(exception, (ctx), *)
159+
def my_handler(ctx, *, exception:)
160160
ctx[:exception_class] = exception.class
161161
end
162162
end
@@ -297,9 +297,9 @@ class Song::Operation::Create < Trailblazer::Activity::Railway
297297
end
298298
assert_equal warnings, ""
299299

300-
# _, warnings = capture_io do
300+
_, warnings = capture_io do
301301
assert_invoke activity, rehash_raise: RuntimeError, terminus: :failure, seq: "[:rehash, :MyHandler]", expected_ctx_variables: {exception_class: RuntimeError}
302-
# end
302+
end
303303
assert_equal warnings, ""
304304
end
305305
end

0 commit comments

Comments
 (0)