Skip to content

Commit b5a4948

Browse files
authoredFeb 4, 2025··
Introduce Configuration#validate (#2537)
* Introduce Configuration#validate * Add a simple validate DSL to Configuration * Remove unused method * Construct error message in the validation itself * Stricter specs * Update CHANGELOG * Fix spec for non-vernier setup
1 parent a8094be commit b5a4948

File tree

4 files changed

+63
-16
lines changed

4 files changed

+63
-16
lines changed
 

‎CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
- Fix handling of cron with tz in Cron::Job ([#2530](https://github.com/getsentry/sentry-ruby/pull/2530))
66
- Revert "[rails] support string errors in error reporter (#2464)" ([#2533](https://github.com/getsentry/sentry-ruby/pull/2533))
7+
- Removed unnecessary warning about missing `stackprof` when Vernier is configured as the profiler ([#2537](https://github.com/getsentry/sentry-ruby/pull/2537))
78

89
## 5.22.3
910

‎sentry-ruby/lib/sentry-ruby.rb

+1
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,7 @@ def init(&block)
232232
yield(config) if block_given?
233233
config.detect_release
234234
apply_patches(config)
235+
config.validate
235236
client = Client.new(config)
236237
scope = Scope.new(max_breadcrumbs: config.max_breadcrumbs)
237238
hub = Hub.new(client, scope)

‎sentry-ruby/lib/sentry/configuration.rb

+57-8
Original file line numberDiff line numberDiff line change
@@ -360,8 +360,47 @@ def post_initialization_callbacks
360360
def add_post_initialization_callback(&block)
361361
post_initialization_callbacks << block
362362
end
363+
364+
def validations
365+
@validations ||= {}
366+
end
367+
368+
def validate(attribute, optional: false, type: nil)
369+
validations[attribute] = {
370+
optional: optional,
371+
type: type,
372+
proc: build_validation_proc(optional, type)
373+
}
374+
end
375+
376+
private
377+
378+
def build_validation_proc(optional, type)
379+
case type
380+
when :numeric
381+
->(value) do
382+
if optional && value.nil?
383+
true
384+
else
385+
unless value.is_a?(Numeric)
386+
message = "must be a Numeric"
387+
message += " or nil" if optional
388+
389+
{ error: message, value: value }
390+
else
391+
true
392+
end
393+
end
394+
end
395+
else
396+
->(value) { true }
397+
end
398+
end
363399
end
364400

401+
validate :traces_sample_rate, optional: true, type: :numeric
402+
validate :profiles_sample_rate, optional: true, type: :numeric
403+
365404
def initialize
366405
self.app_dirs_pattern = APP_DIRS_PATTERN
367406
self.debug = Sentry::Utils::EnvHelper.env_to_bool(ENV["SENTRY_DEBUG"])
@@ -417,6 +456,24 @@ def initialize
417456
run_post_initialization_callbacks
418457
end
419458

459+
def validate
460+
if profiler_class == Sentry::Profiler && !defined?(StackProf)
461+
log_warn("Please add the 'stackprof' gem to your Gemfile to use the StackProf profiler with Sentry.")
462+
end
463+
464+
if profiler_class == Sentry::Vernier::Profiler && !defined?(Vernier)
465+
log_warn("Please add the 'vernier' gem to your Gemfile to use the Vernier profiler with Sentry.")
466+
end
467+
468+
self.class.validations.each do |attribute, validation|
469+
value = public_send(attribute)
470+
471+
next if (result = validation[:proc].call(value)) === true
472+
473+
raise ArgumentError, result[:error]
474+
end
475+
end
476+
420477
def dsn=(value)
421478
@dsn = init_dsn(value)
422479
end
@@ -489,18 +546,11 @@ def enable_tracing=(enable_tracing)
489546
@traces_sample_rate ||= 1.0 if enable_tracing
490547
end
491548

492-
def is_numeric_or_nil?(value)
493-
value.is_a?(Numeric) || value.nil?
494-
end
495-
496549
def traces_sample_rate=(traces_sample_rate)
497-
raise ArgumentError, "traces_sample_rate must be a Numeric or nil" unless is_numeric_or_nil?(traces_sample_rate)
498550
@traces_sample_rate = traces_sample_rate
499551
end
500552

501553
def profiles_sample_rate=(profiles_sample_rate)
502-
raise ArgumentError, "profiles_sample_rate must be a Numeric or nil" unless is_numeric_or_nil?(profiles_sample_rate)
503-
log_warn("Please make sure to include the 'stackprof' gem in your Gemfile to use Profiling with Sentry.") unless defined?(StackProf)
504554
@profiles_sample_rate = profiles_sample_rate
505555
end
506556

@@ -509,7 +559,6 @@ def profiler_class=(profiler_class)
509559
begin
510560
require "vernier"
511561
rescue LoadError
512-
raise ArgumentError, "Please add the 'vernier' gem to your Gemfile to use the Vernier profiler with Sentry."
513562
end
514563
end
515564

‎sentry-ruby/spec/sentry/configuration_spec.rb

+4-8
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,8 @@
9090
end
9191

9292
it "raises ArgumentError when the value is not Numeric nor nil" do
93-
expect { subject.traces_sample_rate = "foobar" }.to raise_error(ArgumentError)
93+
expect { Sentry.init { |config| config.traces_sample_rate = "foobar" } }
94+
.to raise_error(ArgumentError, "must be a Numeric or nil")
9495
end
9596
end
9697

@@ -210,7 +211,8 @@
210211
end
211212

212213
it "raises ArgumentError when the value is not Numeric nor nil" do
213-
expect { subject.profiles_sample_rate = "foobar" }.to raise_error(ArgumentError)
214+
expect { Sentry.init { |config| config.profiles_sample_rate = "foobar" } }
215+
.to raise_error(ArgumentError, "must be a Numeric or nil")
214216
end
215217
end
216218

@@ -703,12 +705,6 @@ class SentryConfigurationSample < Sentry::Configuration
703705
end
704706

705707
it "sets the profiler class to StackProf when Vernier is not available", when: { ruby_version?: [:<, "3.2"] } do
706-
expect { subject.profiler_class = Sentry::Vernier::Profiler }
707-
.to raise_error(
708-
ArgumentError,
709-
/Please add the 'vernier' gem to your Gemfile/
710-
)
711-
712708
expect(subject.profiler_class).to eq(Sentry::Profiler)
713709
end
714710
end

0 commit comments

Comments
 (0)
Please sign in to comment.