From 405a6b7d18347c8563e7310bc0f02fb26aac47c0 Mon Sep 17 00:00:00 2001 From: Peter Solnica Date: Thu, 25 Sep 2025 10:45:38 +0000 Subject: [PATCH 1/3] Yield config from its constructor --- sentry-ruby/lib/sentry-ruby.rb | 3 +-- sentry-ruby/lib/sentry/configuration.rb | 2 ++ 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/sentry-ruby/lib/sentry-ruby.rb b/sentry-ruby/lib/sentry-ruby.rb index c9283641c..e2b6094f8 100644 --- a/sentry-ruby/lib/sentry-ruby.rb +++ b/sentry-ruby/lib/sentry-ruby.rb @@ -239,8 +239,7 @@ def add_attachment(**opts) # @yieldparam config [Configuration] # @return [void] def init(&block) - config = Configuration.new - yield(config) if block_given? + config = Configuration.new(&block) config.detect_release apply_patches(config) diff --git a/sentry-ruby/lib/sentry/configuration.rb b/sentry-ruby/lib/sentry/configuration.rb index cfcf29d89..0c3ca9001 100644 --- a/sentry-ruby/lib/sentry/configuration.rb +++ b/sentry-ruby/lib/sentry/configuration.rb @@ -501,6 +501,8 @@ def initialize run_post_initialization_callbacks self.max_log_events = LogEventBuffer::DEFAULT_MAX_EVENTS + + yield(self) if block_given? end def validate From dc0d361c15c293c8b5d0d8c1906e5af0fee99ef7 Mon Sep 17 00:00:00 2001 From: Peter Solnica Date: Thu, 25 Sep 2025 11:27:17 +0000 Subject: [PATCH 2/3] feat(configuration): add before/after callbacks --- sentry-ruby/lib/sentry/configuration.rb | 30 ++++++++++++++--- sentry-ruby/spec/sentry/configuration_spec.rb | 33 +++++++++++++++++++ 2 files changed, 58 insertions(+), 5 deletions(-) diff --git a/sentry-ruby/lib/sentry/configuration.rb b/sentry-ruby/lib/sentry/configuration.rb index 0c3ca9001..7a93cea1a 100644 --- a/sentry-ruby/lib/sentry/configuration.rb +++ b/sentry-ruby/lib/sentry/configuration.rb @@ -400,7 +400,23 @@ def post_initialization_callbacks # allow extensions to add their hooks to the Configuration class def add_post_initialization_callback(&block) - post_initialization_callbacks << block + callbacks[:initialize][:after] << block + end + + def before(event, &block) + callbacks[event.to_sym][:before] << block + end + + def after(event, &block) + callbacks[event.to_sym][:after] << block + end + + # @!visibility private + def callbacks + @callbacks ||= { + initialize: { before: [], after: [] }, + configured: { before: [], after: [] } + } end def validations @@ -444,6 +460,8 @@ def build_validation_proc(optional, type) validate :profiles_sample_rate, optional: true, type: :numeric def initialize + run_callbacks(:before, :initialize) + self.app_dirs_pattern = APP_DIRS_PATTERN self.debug = Sentry::Utils::EnvHelper.env_to_bool(ENV["SENTRY_DEBUG"]) self.background_worker_threads = (processor_count / 2.0).ceil @@ -498,11 +516,13 @@ def initialize @structured_logging = StructuredLoggingConfiguration.new @gem_specs = Hash[Gem::Specification.map { |spec| [spec.name, spec.version.to_s] }] if Gem::Specification.respond_to?(:map) - run_post_initialization_callbacks - self.max_log_events = LogEventBuffer::DEFAULT_MAX_EVENTS + run_callbacks(:after, :initialize) + yield(self) if block_given? + + run_callbacks(:after, :configured) end def validate @@ -786,8 +806,8 @@ def running_on_heroku? File.directory?("/etc/heroku") && !ENV["CI"] end - def run_post_initialization_callbacks - self.class.post_initialization_callbacks.each do |hook| + def run_callbacks(hook, event) + self.class.callbacks[event][hook].each do |hook| instance_eval(&hook) end end diff --git a/sentry-ruby/spec/sentry/configuration_spec.rb b/sentry-ruby/spec/sentry/configuration_spec.rb index 815943765..92e831466 100644 --- a/sentry-ruby/spec/sentry/configuration_spec.rb +++ b/sentry-ruby/spec/sentry/configuration_spec.rb @@ -605,6 +605,39 @@ class SentryConfigurationSample < Sentry::Configuration end end + describe '.before' do + it 'calls a hook before given event' do + config = Class.new(Sentry::Configuration) do + attr_reader :info + + before(:initialize) do + @info = "debug is #{debug.inspect}" + end + end.new do |config| + config.debug = true + end + + expect(config.info).to eq("debug is nil") + expect(config.debug).to be(true) + end + end + + describe '.after' do + it 'calls a hook after given event' do + config = Class.new(Sentry::Configuration) do + attr_reader :info + + after(:configured) do + @info = "debug was set to #{debug}" + end + end.new do |config| + config.debug = true + end + + expect(config.info).to eq("debug was set to true") + end + end + describe "#skip_rake_integration" do it "returns false by default" do expect(subject.skip_rake_integration).to eq(false) From a3a48b067a04397cc9f0b838306ec325b3b03e37 Mon Sep 17 00:00:00 2001 From: Peter Solnica Date: Thu, 25 Sep 2025 11:29:38 +0000 Subject: [PATCH 3/3] Update CHANGELOG --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2ffcad5bb..defe54f2b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ### Internal - Fix leftover `config.logger` call in `graphql` patch ([#2722](https://github.com/getsentry/sentry-ruby/2722) +- Add `Configuration.before` and `Configuration.after` to run hooks before and after given event ([#2724](https://github.com/getsentry/sentry-ruby/pull/2724)) ## 5.27.1