airbrake-ruby 5.0.1-java → 5.2.1-java

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. checksums.yaml +4 -4
  2. data/lib/airbrake-ruby.rb +4 -2
  3. data/lib/airbrake-ruby/async_sender.rb +3 -1
  4. data/lib/airbrake-ruby/config.rb +15 -6
  5. data/lib/airbrake-ruby/config/processor.rb +7 -20
  6. data/lib/airbrake-ruby/context.rb +51 -0
  7. data/lib/airbrake-ruby/file_cache.rb +1 -1
  8. data/lib/airbrake-ruby/filter_chain.rb +2 -0
  9. data/lib/airbrake-ruby/filters/context_filter.rb +4 -5
  10. data/lib/airbrake-ruby/filters/exception_attributes_filter.rb +1 -1
  11. data/lib/airbrake-ruby/filters/git_last_checkout_filter.rb +1 -1
  12. data/lib/airbrake-ruby/filters/git_revision_filter.rb +1 -1
  13. data/lib/airbrake-ruby/filters/keys_filter.rb +2 -2
  14. data/lib/airbrake-ruby/filters/sql_filter.rb +2 -2
  15. data/lib/airbrake-ruby/filters/thread_filter.rb +2 -3
  16. data/lib/airbrake-ruby/grouppable.rb +1 -1
  17. data/lib/airbrake-ruby/ignorable.rb +0 -2
  18. data/lib/airbrake-ruby/mergeable.rb +1 -1
  19. data/lib/airbrake-ruby/notice_notifier.rb +3 -4
  20. data/lib/airbrake-ruby/performance_notifier.rb +1 -2
  21. data/lib/airbrake-ruby/remote_settings.rb +10 -50
  22. data/lib/airbrake-ruby/remote_settings/callback.rb +44 -0
  23. data/lib/airbrake-ruby/remote_settings/settings_data.rb +3 -8
  24. data/lib/airbrake-ruby/tdigest.rb +7 -6
  25. data/lib/airbrake-ruby/thread_pool.rb +5 -3
  26. data/lib/airbrake-ruby/timed_trace.rb +1 -3
  27. data/lib/airbrake-ruby/version.rb +2 -2
  28. data/spec/airbrake_spec.rb +139 -76
  29. data/spec/async_sender_spec.rb +10 -8
  30. data/spec/backtrace_spec.rb +13 -10
  31. data/spec/benchmark_spec.rb +5 -3
  32. data/spec/code_hunk_spec.rb +24 -15
  33. data/spec/config/processor_spec.rb +29 -87
  34. data/spec/config/validator_spec.rb +5 -2
  35. data/spec/config_spec.rb +26 -17
  36. data/spec/context_spec.rb +54 -0
  37. data/spec/deploy_notifier_spec.rb +6 -4
  38. data/spec/file_cache_spec.rb +1 -0
  39. data/spec/filter_chain_spec.rb +29 -24
  40. data/spec/filters/context_filter_spec.rb +14 -5
  41. data/spec/filters/dependency_filter_spec.rb +3 -1
  42. data/spec/filters/exception_attributes_filter_spec.rb +5 -3
  43. data/spec/filters/gem_root_filter_spec.rb +5 -2
  44. data/spec/filters/git_last_checkout_filter_spec.rb +10 -12
  45. data/spec/filters/git_repository_filter.rb +9 -9
  46. data/spec/filters/git_revision_filter_spec.rb +19 -19
  47. data/spec/filters/keys_allowlist_spec.rb +25 -16
  48. data/spec/filters/keys_blocklist_spec.rb +25 -18
  49. data/spec/filters/root_directory_filter_spec.rb +3 -3
  50. data/spec/filters/sql_filter_spec.rb +26 -26
  51. data/spec/filters/system_exit_filter_spec.rb +4 -2
  52. data/spec/filters/thread_filter_spec.rb +16 -14
  53. data/spec/loggable_spec.rb +2 -2
  54. data/spec/monotonic_time_spec.rb +8 -6
  55. data/spec/nested_exception_spec.rb +46 -46
  56. data/spec/notice_notifier/options_spec.rb +23 -13
  57. data/spec/notice_notifier_spec.rb +52 -47
  58. data/spec/notice_spec.rb +6 -2
  59. data/spec/performance_notifier_spec.rb +67 -60
  60. data/spec/promise_spec.rb +38 -32
  61. data/spec/remote_settings/callback_spec.rb +162 -0
  62. data/spec/remote_settings/settings_data_spec.rb +23 -53
  63. data/spec/remote_settings_spec.rb +42 -75
  64. data/spec/response_spec.rb +34 -12
  65. data/spec/stashable_spec.rb +5 -5
  66. data/spec/stat_spec.rb +7 -5
  67. data/spec/sync_sender_spec.rb +49 -16
  68. data/spec/tdigest_spec.rb +61 -56
  69. data/spec/thread_pool_spec.rb +65 -55
  70. data/spec/time_truncate_spec.rb +4 -2
  71. data/spec/timed_trace_spec.rb +32 -30
  72. data/spec/truncator_spec.rb +72 -43
  73. metadata +53 -47
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e1d429c7130b26f5c2ab1e4616ad7fda8d86a2d973fd00cd97fced1cd9ef84c1
4
- data.tar.gz: a7177673edea3b8f05055683972b918bf43255ad68fc21688317ec5ed56dbb7b
3
+ metadata.gz: 3b991075f1de43dc06d88b8e0a7e674ae99fccfffc0dc5214aa823674fbc9d63
4
+ data.tar.gz: 714f8424b206e2842237c5417833118d2960e1eb0a1c4ff7d16ad75467b9bfc1
5
5
  SHA512:
6
- metadata.gz: b466bc3f67e159a77a72b6b3a24b06166c5c15005de2e658d9a33c3b128eb43d312263760c78f4575204ba61d4108c742975c9ab63676a61159eb1b5ff4a2878
7
- data.tar.gz: b9e6812ed5d2734c7fd3ffd83b14e5d366594366c5460244e43d13375ede211c56d4e1a3b4c79b613de0d480493d9950a833670bb2f59161f1d0db051936b0a1
6
+ metadata.gz: 6f796be1a4661cc7ad536f5fce6771c094ec2683b23f3474cfcea225c259f5adbb0943af6d04269c695abc745c0213699748be273284b101fd3410fc5d0bbb05
7
+ data.tar.gz: af89bef16ed1f0f64b1e65484d680cdd5204905d5981c7a1310d19c9d875cf4ce702b06d51b4c508985b5e1cc7d0a87b33c7cc8a002d673bad11dffa4fc0f248
data/lib/airbrake-ruby.rb CHANGED
@@ -13,6 +13,7 @@ require 'airbrake-ruby/grouppable'
13
13
  require 'airbrake-ruby/config'
14
14
  require 'airbrake-ruby/config/validator'
15
15
  require 'airbrake-ruby/config/processor'
16
+ require 'airbrake-ruby/remote_settings/callback'
16
17
  require 'airbrake-ruby/remote_settings/settings_data'
17
18
  require 'airbrake-ruby/remote_settings'
18
19
  require 'airbrake-ruby/promise'
@@ -57,6 +58,7 @@ require 'airbrake-ruby/benchmark'
57
58
  require 'airbrake-ruby/monotonic_time'
58
59
  require 'airbrake-ruby/timed_trace'
59
60
  require 'airbrake-ruby/queue'
61
+ require 'airbrake-ruby/context'
60
62
 
61
63
  # Airbrake is a thin wrapper around instances of the notifier classes (such as
62
64
  # notice, performance & deploy notifiers). It creates a way to access them via a
@@ -272,7 +274,7 @@ module Airbrake
272
274
  # Airbrake.notify('App crashed!') #=> raises Airbrake::Error
273
275
  #
274
276
  # @return [nil]
275
- # rubocop:disable Style/IfUnlessModifier, Metrics/CyclomaticComplexity
277
+ # rubocop:disable Style/IfUnlessModifier
276
278
  def close
277
279
  if defined?(@notice_notifier) && @notice_notifier
278
280
  @notice_notifier.close
@@ -288,7 +290,7 @@ module Airbrake
288
290
 
289
291
  nil
290
292
  end
291
- # rubocop:enable Style/IfUnlessModifier, Metrics/CyclomaticComplexity
293
+ # rubocop:enable Style/IfUnlessModifier
292
294
 
293
295
  # Pings the Airbrake Deploy API endpoint about the occurred deploy.
294
296
  #
@@ -7,9 +7,10 @@ module Airbrake
7
7
  class AsyncSender
8
8
  include Loggable
9
9
 
10
- def initialize(method = :post)
10
+ def initialize(method = :post, name = 'async-sender')
11
11
  @config = Airbrake::Config.instance
12
12
  @method = method
13
+ @name = name
13
14
  end
14
15
 
15
16
  # Asynchronously sends a notice to Airbrake.
@@ -47,6 +48,7 @@ module Airbrake
47
48
  @thread_pool ||= begin
48
49
  sender = SyncSender.new(@method)
49
50
  ThreadPool.new(
51
+ name: @name,
50
52
  worker_size: @config.workers,
51
53
  queue_size: @config.queue_size,
52
54
  block: proc { |args| sender.send(*args) },
@@ -121,13 +121,21 @@ module Airbrake
121
121
  # @return [Boolean] true if the library should send error reports to
122
122
  # Airbrake, false otherwise
123
123
  # @api public
124
- # @since 5.0.0
124
+ # @since v5.0.0
125
125
  attr_accessor :error_notifications
126
126
 
127
- # @return [String] the host such as which should be used for fetching remote
128
- # configuration options (example: "https://bucket-name.s3.amazonaws.com")
127
+ # @return [String] the host which should be used for fetching remote
128
+ # configuration options
129
+ # @api public
130
+ # @since v5.0.0
129
131
  attr_accessor :remote_config_host
130
132
 
133
+ # @return [String] true if notifier should periodically fetch remote
134
+ # configuration, false otherwise
135
+ # @api public
136
+ # @since v5.2.0
137
+ attr_accessor :remote_config
138
+
131
139
  class << self
132
140
  # @return [Config]
133
141
  attr_writer :instance
@@ -140,7 +148,7 @@ module Airbrake
140
148
 
141
149
  # @param [Hash{Symbol=>Object}] user_config the hash to be used to build the
142
150
  # config
143
- # rubocop:disable Metrics/AbcSize
151
+ # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
144
152
  def initialize(user_config = {})
145
153
  self.proxy = {}
146
154
  self.queue_size = 100
@@ -151,7 +159,7 @@ module Airbrake
151
159
  self.project_key = user_config[:project_key]
152
160
  self.error_host = 'https://api.airbrake.io'
153
161
  self.apm_host = 'https://api.airbrake.io'
154
- self.remote_config_host = 'https://v1-production-notifier-configs.s3.amazonaws.com'
162
+ self.remote_config_host = 'https://notifier-configs.airbrake.io'
155
163
 
156
164
  self.ignore_environments = []
157
165
 
@@ -171,10 +179,11 @@ module Airbrake
171
179
  self.query_stats = true
172
180
  self.job_stats = true
173
181
  self.error_notifications = true
182
+ self.remote_config = true
174
183
 
175
184
  merge(user_config)
176
185
  end
177
- # rubocop:enable Metrics/AbcSize
186
+ # rubocop:enable Metrics/AbcSize, Metrics/MethodLength
178
187
 
179
188
  # The full URL to the Airbrake Notice API. Based on the +:error_host+ option.
180
189
  # @return [URI] the endpoint address
@@ -3,7 +3,7 @@ module Airbrake
3
3
  # Processor is a helper class, which is responsible for setting default
4
4
  # config values, default notifier filters and remote configuration changes.
5
5
  #
6
- # @since 5.0.0
6
+ # @since v5.0.0
7
7
  # @api private
8
8
  class Processor
9
9
  # @param [Airbrake::Config] config
@@ -18,6 +18,7 @@ module Airbrake
18
18
  @blocklist_keys = @config.blocklist_keys
19
19
  @allowlist_keys = @config.allowlist_keys
20
20
  @project_id = @config.project_id
21
+ @poll_callback = Airbrake::RemoteSettings::Callback.new(config)
21
22
  end
22
23
 
23
24
  # @param [Airbrake::NoticeNotifier] notifier
@@ -40,13 +41,13 @@ module Airbrake
40
41
 
41
42
  # @return [Airbrake::RemoteSettings]
42
43
  def process_remote_configuration
44
+ return unless @config.remote_config
43
45
  return unless @project_id
46
+ return if @config.environment == 'test'
44
47
 
45
- RemoteSettings.poll(
46
- @project_id,
47
- @config.remote_config_host,
48
- &method(:poll_callback)
49
- )
48
+ RemoteSettings.poll(@project_id, @config.remote_config_host) do |data|
49
+ @poll_callback.call(data)
50
+ end
50
51
  end
51
52
 
52
53
  # @param [Airbrake::NoticeNotifier] notifier
@@ -65,20 +66,6 @@ module Airbrake
65
66
  notifier.add_filter(filter.new(@config.root_directory))
66
67
  end
67
68
  end
68
-
69
- # @param [Airbrake::RemoteSettings::SettingsData] data
70
- # @return [void]
71
- def poll_callback(data)
72
- @config.logger.debug(
73
- "#{LOG_LABEL} applying remote settings: #{data.to_h}",
74
- )
75
-
76
- @config.error_host = data.error_host if data.error_host
77
- @config.apm_host = data.apm_host if data.apm_host
78
-
79
- @config.error_notifications = data.error_notifications?
80
- @config.performance_stats = data.performance_stats?
81
- end
82
69
  end
83
70
  end
84
71
  end
@@ -0,0 +1,51 @@
1
+ module Airbrake
2
+ # Represents a thread-safe Airbrake context object, which carries arbitrary
3
+ # information added via {Airbrake.merge_context} calls.
4
+ #
5
+ # @example
6
+ # Airbrake::Context.current.merge!(foo: 'bar')
7
+ #
8
+ # @api private
9
+ # @since v5.2.1
10
+ class Context
11
+ # Returns current, thread-local, context.
12
+ # @return [self]
13
+ def self.current
14
+ Thread.current[:airbrake_context] ||= new
15
+ end
16
+
17
+ def initialize
18
+ @mutex = Mutex.new
19
+ @context = {}
20
+ end
21
+
22
+ # Merges the given context with the current one.
23
+ #
24
+ # @param [Hash{Object=>Object}] other
25
+ # @return [void]
26
+ def merge!(other)
27
+ @mutex.synchronize do
28
+ @context.merge!(other)
29
+ end
30
+ end
31
+
32
+ # @return [Hash] duplicated Hash context
33
+ def to_h
34
+ @mutex.synchronize do
35
+ @context.dup
36
+ end
37
+ end
38
+
39
+ # @return [Hash] clears (resets) the current context
40
+ def clear
41
+ @mutex.synchronize do
42
+ @context.clear
43
+ end
44
+ end
45
+
46
+ # @return [Boolean] checks whether the context has any data
47
+ def empty?
48
+ @context.empty?
49
+ end
50
+ end
51
+ end
@@ -40,7 +40,7 @@ module Airbrake
40
40
  data.empty?
41
41
  end
42
42
 
43
- # @since 4.7.0
43
+ # @since v4.7.0
44
44
  # @return [void]
45
45
  def self.reset
46
46
  @data = {}
@@ -57,7 +57,9 @@ module Airbrake
57
57
  # @return [void]
58
58
  # @since v3.1.0
59
59
  def delete_filter(filter_class)
60
+ # rubocop:disable Style/ClassEqualityComparison
60
61
  index = @filters.index { |f| f.class.name == filter_class.name }
62
+ # rubocop:enable Style/ClassEqualityComparison
61
63
  @filters.delete_at(index) if index
62
64
  end
63
65
 
@@ -9,8 +9,7 @@ module Airbrake
9
9
  # @return [Integer]
10
10
  attr_reader :weight
11
11
 
12
- def initialize(context)
13
- @context = context
12
+ def initialize
14
13
  @weight = 119
15
14
  @mutex = Mutex.new
16
15
  end
@@ -18,10 +17,10 @@ module Airbrake
18
17
  # @macro call_filter
19
18
  def call(notice)
20
19
  @mutex.synchronize do
21
- return if @context.empty?
20
+ return if Airbrake::Context.current.empty?
22
21
 
23
- notice[:params][:airbrake_context] = @context.dup
24
- @context.clear
22
+ notice[:params][:airbrake_context] = Airbrake::Context.current.to_h
23
+ Airbrake::Context.current.clear
25
24
  end
26
25
  end
27
26
  end
@@ -13,7 +13,7 @@ module Airbrake
13
13
  end
14
14
 
15
15
  # @macro call_filter
16
- def call(notice)
16
+ def call(notice) # rubocop:disable Metrics/AbcSize
17
17
  exception = notice.stash[:exception]
18
18
  return unless exception.respond_to?(:to_airbrake)
19
19
 
@@ -50,7 +50,7 @@ module Airbrake
50
50
  def last_checkout
51
51
  return unless (line = last_checkout_line)
52
52
 
53
- parts = line.chomp.split("\t").first.split(' ')
53
+ parts = line.chomp.split("\t").first.split
54
54
  if parts.size < MIN_HEAD_COLS
55
55
  logger.error(
56
56
  "#{LOG_LABEL} Airbrake::#{self.class.name}: can't parse line: #{line}",
@@ -57,7 +57,7 @@ module Airbrake
57
57
 
58
58
  File.readlines(packed_refs_path).each do |line|
59
59
  next if %w[# ^].include?(line[0])
60
- next unless (parts = line.split(' ')).size == 2
60
+ next unless (parts = line.split).size == 2
61
61
  return parts.first if parts.last == head
62
62
  end
63
63
 
@@ -82,7 +82,7 @@ module Airbrake
82
82
 
83
83
  private
84
84
 
85
- def filter_hash(hash)
85
+ def filter_hash(hash) # rubocop:disable Metrics/AbcSize
86
86
  return hash unless hash.is_a?(Hash)
87
87
 
88
88
  hash_copy = hash.dup
@@ -103,7 +103,7 @@ module Airbrake
103
103
  end
104
104
 
105
105
  def filter_url_params(url)
106
- url.query = Hash[URI.decode_www_form(url.query)].map do |key, val|
106
+ url.query = URI.decode_www_form(url.query).to_h.map do |key, val|
107
107
  should_filter?(key) ? "#{key}=[Filtered]" : "#{key}=#{val}"
108
108
  end.join('&')
109
109
 
@@ -27,13 +27,13 @@ module Airbrake
27
27
  single_quotes: /'(?:[^']|'')*?(?:\\'.*|'(?!'))/,
28
28
  double_quotes: /"(?:[^"]|"")*?(?:\\".*|"(?!"))/,
29
29
  dollar_quotes: /(\$(?!\d)[^$]*?\$).*?(?:\1|$)/,
30
- uuids: /\{?(?:[0-9a-fA-F]\-*){32}\}?/,
30
+ uuids: /\{?(?:[0-9a-fA-F]-*){32}\}?/,
31
31
  numeric_literals: /\b-?(?:[0-9]+\.)?[0-9]+([eE][+-]?[0-9]+)?\b/,
32
32
  boolean_literals: /\b(?:true|false|null)\b/i,
33
33
  hexadecimal_literals: /0x[0-9a-fA-F]+/,
34
34
  comments: /(?:#|--).*?(?=\r|\n|$)/i,
35
35
  multi_line_comments: %r{/\*(?:[^/]|/[^*])*?(?:\*/|/\*.*)},
36
- oracle_quoted_strings: /q'\[.*?(?:\]'|$)|q'\{.*?(?:\}'|$)|q'\<.*?(?:\>'|$)|q'\(.*?(?:\)'|$)/,
36
+ oracle_quoted_strings: /q'\[.*?(?:\]'|$)|q'\{.*?(?:\}'|$)|q'<.*?(?:>'|$)|q'\(.*?(?:\)'|$)/,
37
37
  # rubocop:enable Layout/LineLength
38
38
  }.freeze
39
39
 
@@ -41,8 +41,7 @@ module Airbrake
41
41
  thread_info[:fiber_variables] = vars
42
42
  end
43
43
 
44
- # Present in Ruby 2.3+.
45
- if th.respond_to?(:name) && (name = th.name)
44
+ if (name = th.name)
46
45
  thread_info[:name] = name
47
46
  end
48
47
 
@@ -84,7 +83,7 @@ module Airbrake
84
83
  when Array
85
84
  value = value.map { |elem| sanitize_value(elem) }
86
85
  when Hash
87
- Hash[value.map { |k, v| [k, sanitize_value(v)] }]
86
+ value.transform_values { |v| sanitize_value(v) }
88
87
  else
89
88
  value.to_s
90
89
  end
@@ -2,7 +2,7 @@ module Airbrake
2
2
  # Grouppable adds the `#groups` method, so that we don't need to define it in
3
3
  # all of performance models every time we add a model without groups.
4
4
  #
5
- # @since 4.9.0
5
+ # @since v4.9.0
6
6
  # @api private
7
7
  module Grouppable
8
8
  def groups
@@ -18,11 +18,9 @@ module Airbrake
18
18
  # Checks whether the instance was ignored.
19
19
  # @return [Boolean]
20
20
  # @see #ignore!
21
- # rubocop:disable Style/DoubleNegation
22
21
  def ignored?
23
22
  !!ignored
24
23
  end
25
- # rubocop:enable Style/DoubleNegation
26
24
 
27
25
  # Ignores an instance. Ignored instances must never reach the Airbrake
28
26
  # dashboard.
@@ -2,7 +2,7 @@ module Airbrake
2
2
  # Mergeable adds the `#merge` method, so that we don't need to define it in
3
3
  # all of performance models every time we add a model.
4
4
  #
5
- # @since 4.9.0
5
+ # @since v4.9.0
6
6
  # @api private
7
7
  module Mergeable
8
8
  def merge(_other)
@@ -20,14 +20,13 @@ module Airbrake
20
20
 
21
21
  def initialize
22
22
  @config = Airbrake::Config.instance
23
- @context = {}
24
23
  @filter_chain = FilterChain.new
25
- @async_sender = AsyncSender.new
24
+ @async_sender = AsyncSender.new(:post, self.class.name)
26
25
  @sync_sender = SyncSender.new
27
26
 
28
27
  DEFAULT_FILTERS.each { |filter| add_filter(filter.new) }
29
28
 
30
- add_filter(Airbrake::Filters::ContextFilter.new(@context))
29
+ add_filter(Airbrake::Filters::ContextFilter.new)
31
30
  add_filter(Airbrake::Filters::ExceptionAttributesFilter.new)
32
31
  end
33
32
 
@@ -79,7 +78,7 @@ module Airbrake
79
78
 
80
79
  # @see Airbrake.merge_context
81
80
  def merge_context(context)
82
- @context.merge!(context)
81
+ Airbrake::Context.current.merge!(context)
83
82
  end
84
83
 
85
84
  # @return [Boolean]
@@ -12,7 +12,7 @@ module Airbrake
12
12
  def initialize
13
13
  @config = Airbrake::Config.instance
14
14
  @flush_period = Airbrake::Config.instance.performance_stats_flush_period
15
- @async_sender = AsyncSender.new(:put)
15
+ @async_sender = AsyncSender.new(:put, self.class.name)
16
16
  @sync_sender = SyncSender.new(:put)
17
17
  @schedule_flush = nil
18
18
  @filter_chain = FilterChain.new
@@ -51,7 +51,6 @@ module Airbrake
51
51
  @payload.synchronize do
52
52
  @schedule_flush.kill if @schedule_flush
53
53
  @async_sender.close
54
- logger.debug("#{LOG_LABEL} performance notifier closed")
55
54
  end
56
55
  end
57
56
 
@@ -8,22 +8,11 @@ module Airbrake
8
8
  # config.error_notifications = data.error_notifications?
9
9
  # end
10
10
  #
11
- # When {#poll} is called, it will try to load remote settings from disk, so
12
- # that it doesn't wait on the result from the API call.
13
- #
14
- # When {#stop_polling} is called, the current config will be dumped to disk.
15
- #
16
- # @since 5.0.0
11
+ # @since v5.0.0
17
12
  # @api private
18
13
  class RemoteSettings
19
14
  include Airbrake::Loggable
20
15
 
21
- # @return [String] the path to the persistent config
22
- CONFIG_DUMP_PATH = File.join(
23
- File.expand_path(__dir__),
24
- '../../config/config.json',
25
- ).freeze
26
-
27
16
  # @return [Hash{Symbol=>String}] metadata to be attached to every GET
28
17
  # request
29
18
  QUERY_PARAMS = URI.encode_www_form(
@@ -33,6 +22,9 @@ module Airbrake
33
22
  language: "#{RUBY_ENGINE}/#{RUBY_VERSION}".freeze,
34
23
  ).freeze
35
24
 
25
+ # @return [String]
26
+ HTTP_OK = '200'.freeze
27
+
36
28
  # Polls remote config of the given project.
37
29
  #
38
30
  # @param [Integer] project_id
@@ -54,18 +46,11 @@ module Airbrake
54
46
  @poll = nil
55
47
  end
56
48
 
57
- # Polls remote config of the given project in background. Loads local config
58
- # first (if exists).
49
+ # Polls remote config of the given project in background.
59
50
  #
60
51
  # @return [self]
61
52
  def poll
62
53
  @poll ||= Thread.new do
63
- begin
64
- load_config
65
- rescue StandardError => ex
66
- logger.error("#{LOG_LABEL} config loading failed: #{ex}")
67
- end
68
-
69
54
  @block.call(@data)
70
55
 
71
56
  loop do
@@ -77,17 +62,11 @@ module Airbrake
77
62
  self
78
63
  end
79
64
 
80
- # Stops the background poller thread. Dumps current config to disk.
65
+ # Stops the background poller thread.
81
66
  #
82
67
  # @return [void]
83
68
  def stop_polling
84
69
  @poll.kill if @poll
85
-
86
- begin
87
- dump_config
88
- rescue StandardError => ex
89
- logger.error("#{LOG_LABEL} config dumping failed: #{ex}")
90
- end
91
70
  end
92
71
 
93
72
  private
@@ -95,22 +74,20 @@ module Airbrake
95
74
  def fetch_config
96
75
  response = nil
97
76
  begin
98
- response = Net::HTTP.get(build_config_uri)
77
+ response = Net::HTTP.get_response(build_config_uri)
99
78
  rescue StandardError => ex
100
79
  logger.error(ex)
101
80
  return {}
102
81
  end
103
82
 
104
- # AWS S3 API returns XML when request is not valid. In this case we just
105
- # print the returned body and exit the method.
106
- if response.start_with?('<?xml ')
107
- logger.error(response)
83
+ unless response.code == HTTP_OK
84
+ logger.error(response.body)
108
85
  return {}
109
86
  end
110
87
 
111
88
  json = nil
112
89
  begin
113
- json = JSON.parse(response)
90
+ json = JSON.parse(response.body)
114
91
  rescue JSON::ParserError => ex
115
92
  logger.error(ex)
116
93
  return {}
@@ -124,22 +101,5 @@ module Airbrake
124
101
  uri.query = QUERY_PARAMS
125
102
  uri
126
103
  end
127
-
128
- def load_config
129
- config_dir = File.dirname(CONFIG_DUMP_PATH)
130
- Dir.mkdir(config_dir) unless File.directory?(config_dir)
131
-
132
- return unless File.exist?(CONFIG_DUMP_PATH)
133
-
134
- config = File.read(CONFIG_DUMP_PATH)
135
- @data.merge!(JSON.parse(config))
136
- end
137
-
138
- def dump_config
139
- config_dir = File.dirname(CONFIG_DUMP_PATH)
140
- Dir.mkdir(config_dir) unless File.directory?(config_dir)
141
-
142
- File.write(CONFIG_DUMP_PATH, JSON.dump(@data.to_h))
143
- end
144
104
  end
145
105
  end