@@ -89,11 +89,7 @@ def initialize(settings, serializer, logger, code_tracker: nil, telemetry: nil)
8989 # from the method but from outside of the method).
9090 Location = Struct . new ( :path , :lineno , :label )
9191
92- def hook_method ( probe , &block )
93- unless block
94- raise ArgumentError , 'block is required'
95- end
96-
92+ def hook_method ( probe , responder )
9793 lock . synchronize do
9894 if probe . instrumentation_module
9995 # Already instrumented, warn?
@@ -130,10 +126,34 @@ def hook_method(probe, &block)
130126 caller_locations : caller_locations ,
131127 )
132128 continue = condition . satisfied? ( context )
133- rescue
134- raise if settings . dynamic_instrumentation . internal . propagate_all_exceptions
129+ rescue => exc
130+ # Evaluation error exception can be raised for "expected"
131+ # errors, we probably need another setting to control whether
132+ # these exceptions are propagated.
133+ raise if settings . dynamic_instrumentation . internal . propagate_all_exceptions &&
134+ !exc . is_a? ( DI ::Error ::ExpressionEvaluationError )
135+
136+ if context
137+ # We want to report evaluation errors for conditions
138+ # as probe snapshots. However, if we failed to create
139+ # the context, we won't be able to report anything as
140+ # the probe notifier builder requires a context.
141+ begin
142+ responder . probe_condition_evaluation_failed_callback ( context , exc )
143+ rescue
144+ raise if settings . dynamic_instrumentation . internal . propagate_all_exceptions
145+
146+ # TODO log / report via telemetry?
147+ end
148+ else
149+ _ = 42 # stop standard from wrecking this code
150+
151+ raise if settings . dynamic_instrumentation . internal . propagate_all_exceptions
152+
153+ # TODO log / report via telemetry?
154+ # If execution gets here, there is probably a bug in the tracer.
155+ end
135156
136- # TODO log / report via telemetry?
137157 continue = false
138158 end
139159 end
@@ -195,8 +215,7 @@ def hook_method(probe, &block)
195215 caller_locations : caller_locs ,
196216 return_value : rv , duration : duration , exception : exc , )
197217
198- # & is to stop steep complaints, block is always present here.
199- block &.call ( context )
218+ responder . probe_executed_callback ( context )
200219 if exc
201220 raise exc
202221 else
@@ -258,11 +277,7 @@ def unhook_method(probe)
258277 # not for eval'd code, unless the eval'd code is associated with
259278 # a file name and client invokes this method with the correct
260279 # file name for the eval'd code.
261- def hook_line ( probe , &block )
262- unless block
263- raise ArgumentError , 'No block given to hook_line'
264- end
265-
280+ def hook_line ( probe , responder )
266281 lock . synchronize do
267282 if probe . instrumentation_trace_point
268283 # Already instrumented, warn?
@@ -367,14 +382,44 @@ def hook_line(probe, &block)
367382
368383 if continue
369384 if condition = probe . condition
370- context = Context . new (
371- locals : Instrumenter . get_local_variables ( tp ) ,
372- target_self : tp . self ,
373- probe : probe , settings : settings , serializer : serializer ,
374- path : tp . path ,
375- caller_locations : caller_locations ,
376- )
377- continue = condition . satisfied? ( context )
385+ begin
386+ context = Context . new (
387+ locals : Instrumenter . get_local_variables ( tp ) ,
388+ target_self : tp . self ,
389+ probe : probe , settings : settings , serializer : serializer ,
390+ path : tp . path ,
391+ caller_locations : caller_locations ,
392+ )
393+ continue = condition . satisfied? ( context )
394+ rescue => exc
395+ # Evaluation error exception can be raised for "expected"
396+ # errors, we probably need another setting to control whether
397+ # these exceptions are propagated.
398+ raise if settings . dynamic_instrumentation . internal . propagate_all_exceptions &&
399+ !exc . is_a? ( DI ::Error ::ExpressionEvaluationError )
400+
401+ continue = false
402+ if context
403+ # We want to report evaluation errors for conditions
404+ # as probe snapshots. However, if we failed to create
405+ # the context, we won't be able to report anything as
406+ # the probe notifier builder requires a context.
407+ begin
408+ responder . probe_condition_evaluation_failed_callback ( context , condition , exc )
409+ rescue
410+ raise if settings . dynamic_instrumentation . internal . propagate_all_exceptions
411+
412+ # TODO log / report via telemetry?
413+ end
414+ else
415+ _ = 42 # stop standard from wrecking this code
416+
417+ raise if settings . dynamic_instrumentation . internal . propagate_all_exceptions
418+
419+ # TODO log / report via telemetry?
420+ # If execution gets here, there is probably a bug in the tracer.
421+ end
422+ end
378423 end
379424 end
380425
@@ -393,8 +438,7 @@ def hook_line(probe, &block)
393438 caller_locations : caller_locations ,
394439 )
395440
396- # & is to stop steep complaints, block is always present here.
397- block &.call ( context )
441+ responder . probe_executed_callback ( context )
398442 end
399443 rescue => exc
400444 raise if settings . dynamic_instrumentation . internal . propagate_all_exceptions
@@ -445,11 +489,11 @@ def unhook_line(probe)
445489 end
446490 end
447491
448- def hook ( probe , & block )
492+ def hook ( probe , responder )
449493 if probe . method?
450- hook_method ( probe , & block )
494+ hook_method ( probe , responder )
451495 elsif probe . line?
452- hook_line ( probe , & block )
496+ hook_line ( probe , responder )
453497 else
454498 # TODO add test coverage for this path
455499 logger . debug { "di: unknown probe type to hook: #{ probe } " }
0 commit comments