rollbar 2.19.1 → 2.27.1

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 (86) hide show
  1. checksums.yaml +5 -5
  2. data/.github/pull_request_template.md +25 -0
  3. data/.rubocop.yml +168 -0
  4. data/.travis.yml +63 -34
  5. data/Appraisals +10 -10
  6. data/Gemfile +35 -14
  7. data/README.md +5 -2
  8. data/Rakefile +0 -0
  9. data/data/rollbar.snippet.js +1 -1
  10. data/docs/configuration.md +17 -0
  11. data/gemfiles/rails30.gemfile +10 -10
  12. data/gemfiles/rails31.gemfile +10 -9
  13. data/gemfiles/rails32.gemfile +10 -9
  14. data/gemfiles/rails40.gemfile +10 -9
  15. data/gemfiles/rails41.gemfile +10 -9
  16. data/gemfiles/rails42.gemfile +12 -9
  17. data/gemfiles/rails50.gemfile +21 -14
  18. data/gemfiles/rails51.gemfile +21 -14
  19. data/gemfiles/rails52.gemfile +15 -12
  20. data/gemfiles/rails60.gemfile +67 -0
  21. data/lib/generators/rollbar/rollbar_generator.rb +1 -1
  22. data/lib/rails/rollbar_runner.rb +4 -2
  23. data/lib/rollbar/capistrano.rb +1 -1
  24. data/lib/rollbar/capistrano3.rb +6 -3
  25. data/lib/rollbar/capistrano_tasks.rb +29 -21
  26. data/lib/rollbar/configuration.rb +86 -16
  27. data/lib/rollbar/delay/girl_friday.rb +4 -8
  28. data/lib/rollbar/delay/resque.rb +3 -6
  29. data/lib/rollbar/delay/sidekiq.rb +4 -10
  30. data/lib/rollbar/delay/sucker_punch.rb +16 -19
  31. data/lib/rollbar/delay/thread.rb +16 -2
  32. data/lib/rollbar/deploy.rb +52 -29
  33. data/lib/rollbar/encoding/encoder.rb +17 -10
  34. data/lib/rollbar/exception_reporter.rb +19 -5
  35. data/lib/rollbar/item/backtrace.rb +13 -3
  36. data/lib/rollbar/item/frame.rb +9 -1
  37. data/lib/rollbar/item/locals.rb +100 -0
  38. data/lib/rollbar/item.rb +56 -17
  39. data/lib/rollbar/json.rb +6 -51
  40. data/lib/rollbar/language_support.rb +4 -20
  41. data/lib/rollbar/lazy_store.rb +5 -5
  42. data/lib/rollbar/logger.rb +1 -0
  43. data/lib/rollbar/logger_proxy.rb +6 -2
  44. data/lib/rollbar/middleware/js.rb +28 -18
  45. data/lib/rollbar/middleware/rack.rb +4 -1
  46. data/lib/rollbar/middleware/rails/rollbar.rb +10 -1
  47. data/lib/rollbar/notifier/trace_with_bindings.rb +65 -0
  48. data/lib/rollbar/notifier.rb +225 -89
  49. data/lib/rollbar/plugin.rb +54 -6
  50. data/lib/rollbar/plugins/active_job.rb +6 -2
  51. data/lib/rollbar/plugins/basic_socket.rb +21 -6
  52. data/lib/rollbar/plugins/delayed_job/job_data.rb +3 -3
  53. data/lib/rollbar/plugins/delayed_job/plugin.rb +13 -3
  54. data/lib/rollbar/plugins/error_context.rb +11 -0
  55. data/lib/rollbar/plugins/goalie.rb +11 -3
  56. data/lib/rollbar/plugins/rails/controller_methods.rb +15 -3
  57. data/lib/rollbar/plugins/rake.rb +2 -2
  58. data/lib/rollbar/plugins/sidekiq/plugin.rb +5 -4
  59. data/lib/rollbar/plugins.rb +7 -1
  60. data/lib/rollbar/rake_tasks.rb +4 -148
  61. data/lib/rollbar/request_data_extractor.rb +31 -21
  62. data/lib/rollbar/rollbar_test.rb +36 -0
  63. data/lib/rollbar/scrubbers/params.rb +19 -18
  64. data/lib/rollbar/scrubbers/url.rb +18 -9
  65. data/lib/rollbar/scrubbers.rb +3 -3
  66. data/lib/rollbar/truncation/frames_strategy.rb +1 -1
  67. data/lib/rollbar/truncation/min_body_strategy.rb +2 -3
  68. data/lib/rollbar/truncation/mixin.rb +1 -1
  69. data/lib/rollbar/truncation/remove_any_key_strategy.rb +123 -0
  70. data/lib/rollbar/truncation/remove_extra_strategy.rb +35 -0
  71. data/lib/rollbar/truncation/remove_request_strategy.rb +21 -0
  72. data/lib/rollbar/truncation/strings_strategy.rb +6 -5
  73. data/lib/rollbar/truncation.rb +9 -2
  74. data/lib/rollbar/util/hash.rb +15 -0
  75. data/lib/rollbar/util/ip_anonymizer.rb +8 -7
  76. data/lib/rollbar/util/ip_obfuscator.rb +1 -1
  77. data/lib/rollbar/util.rb +6 -2
  78. data/lib/rollbar/version.rb +1 -1
  79. data/lib/rollbar.rb +2 -3
  80. data/lib/tasks/benchmark.rake +103 -0
  81. data/rollbar.gemspec +13 -5
  82. data/spec/support/rollbar_api.rb +67 -0
  83. metadata +21 -23
  84. data/gemfiles/ruby_1_8_and_1_9_2.gemfile +0 -49
  85. data/lib/rollbar/json/default.rb +0 -11
  86. data/lib/rollbar/json/oj.rb +0 -16
@@ -1,9 +1,8 @@
1
1
  module Rollbar
2
2
  module Encoding
3
3
  class Encoder
4
- ALL_ENCODINGS = [::Encoding::UTF_8, ::Encoding::ISO_8859_1, ::Encoding::ASCII_8BIT, ::Encoding::US_ASCII]
5
- ASCII_ENCODINGS = [::Encoding::US_ASCII, ::Encoding::ASCII_8BIT, ::Encoding::ISO_8859_1]
6
- ENCODING_OPTIONS = { :invalid => :replace, :undef => :replace, :replace => '' }
4
+ ALL_ENCODINGS = [::Encoding::UTF_8, ::Encoding::ISO_8859_1, ::Encoding::ASCII_8BIT, ::Encoding::US_ASCII].freeze
5
+ ASCII_ENCODINGS = [::Encoding::US_ASCII, ::Encoding::ASCII_8BIT, ::Encoding::ISO_8859_1].freeze
7
6
  UTF8 = 'UTF-8'.freeze
8
7
  BINARY = 'binary'.freeze
9
8
 
@@ -18,13 +17,22 @@ module Rollbar
18
17
  encoding = value.encoding
19
18
 
20
19
  # This will be most of cases so avoid force anything for them
21
- if encoding == ::Encoding::UTF_8 && value.valid_encoding?
22
- encoded_value = value
23
- else
24
- encoded_value = force_encoding(value).encode(*encoding_args(value))
25
- end
20
+ encoded_value = if encoding == ::Encoding::UTF_8 && value.valid_encoding?
21
+ value
22
+ else
23
+ force_encoding(value).encode(
24
+ *encoding_args(value),
25
+ # Ruby 2.7 requires this to look like keyword args,
26
+ # and Ruby 1.9.3 doesn't understand keyword args, so
27
+ # don't use hash rockets here and both will be happy.
28
+ invalid: :replace, undef: :replace, replace: '' # rubocop:disable Style/HashSyntax
29
+ )
30
+ end
26
31
 
27
32
  object.is_a?(Symbol) ? encoded_value.to_sym : encoded_value
33
+ rescue StandardError => e
34
+ # If encoding fails for any reason, replace the string with a diagnostic error.
35
+ "error encoding string: #{e.class}: #{e.message}"
28
36
  end
29
37
 
30
38
  private
@@ -45,7 +53,7 @@ module Rollbar
45
53
  # Seems #codepoints is faster than #valid_encoding?
46
54
  value.force_encoding(encoding).encode(::Encoding::UTF_8).codepoints
47
55
  true
48
- rescue
56
+ rescue StandardError
49
57
  false
50
58
  end
51
59
  end
@@ -54,7 +62,6 @@ module Rollbar
54
62
  def encoding_args(value)
55
63
  args = [UTF8]
56
64
  args << BINARY if ASCII_ENCODINGS.include?(value.encoding)
57
- args << ENCODING_OPTIONS
58
65
 
59
66
  args
60
67
  end
@@ -1,10 +1,11 @@
1
1
  module Rollbar
2
- module ExceptionReporter
2
+ module ExceptionReporter # :nodoc:
3
3
  def report_exception_to_rollbar(env, exception)
4
- exception_message = exception.respond_to?(:message) ? exception.message : 'No Exception Message'
5
- Rollbar.log_debug "[Rollbar] Reporting exception: #{exception_message}"
4
+ return unless capture_uncaught?
5
+
6
+ log_exception_message(exception)
6
7
 
7
- exception_data = Rollbar.log(Rollbar.configuration.uncaught_exception_level, exception, :use_exception_level_filters => true)
8
+ exception_data = exception_data(exception)
8
9
 
9
10
  if exception_data.is_a?(Hash)
10
11
  env['rollbar.exception_uuid'] = exception_data[:uuid]
@@ -14,8 +15,21 @@ module Rollbar
14
15
  elsif exception_data == 'ignored'
15
16
  Rollbar.log_debug '[Rollbar] Exception not reported because it was ignored'
16
17
  end
17
- rescue => e
18
+ rescue StandardError => e
18
19
  Rollbar.log_warning "[Rollbar] Exception while reporting exception to Rollbar: #{e.message}"
19
20
  end
21
+
22
+ def capture_uncaught?
23
+ Rollbar.configuration.capture_uncaught != false
24
+ end
25
+
26
+ def log_exception_message(exception)
27
+ exception_message = exception.respond_to?(:message) ? exception.message : 'No Exception Message'
28
+ Rollbar.log_debug "[Rollbar] Reporting exception: #{exception_message}"
29
+ end
30
+
31
+ def exception_data(exception)
32
+ Rollbar.log(Rollbar.configuration.uncaught_exception_level, exception, :use_exception_level_filters => true)
33
+ end
20
34
  end
21
35
  end
@@ -32,7 +32,7 @@ module Rollbar
32
32
  end
33
33
  end
34
34
 
35
- alias_method :build, :to_h
35
+ alias build to_h
36
36
 
37
37
  def get_file_lines(filename)
38
38
  files[filename] ||= read_file(filename)
@@ -44,7 +44,7 @@ module Rollbar
44
44
  return unless File.exist?(filename)
45
45
 
46
46
  File.read(filename).split("\n")
47
- rescue
47
+ rescue StandardError
48
48
  nil
49
49
  end
50
50
 
@@ -74,10 +74,20 @@ module Rollbar
74
74
  end
75
75
 
76
76
  def map_frames(current_exception)
77
- exception_backtrace(current_exception).reverse.map do |frame|
77
+ frames = cleaned_backtrace(current_exception).map do |frame|
78
78
  Rollbar::Item::Frame.new(self, frame,
79
79
  :configuration => configuration).to_h
80
80
  end
81
+ frames.reverse!
82
+ end
83
+
84
+ def cleaned_backtrace(current_exception)
85
+ normalized_backtrace = exception_backtrace(current_exception)
86
+ if configuration.backtrace_cleaner
87
+ configuration.backtrace_cleaner.clean(normalized_backtrace)
88
+ else
89
+ normalized_backtrace
90
+ end
81
91
  end
82
92
 
83
93
  # Returns the backtrace to be sent to our API. There are 3 options:
@@ -1,5 +1,6 @@
1
1
  # We want to use Gem.path
2
2
  require 'rubygems'
3
+ require 'rollbar/item/locals'
3
4
 
4
5
  module Rollbar
5
6
  class Item
@@ -47,7 +48,8 @@ module Rollbar
47
48
 
48
49
  {
49
50
  :code => code_data(file_lines, lineno),
50
- :context => context_data(file_lines, lineno)
51
+ :context => context_data(file_lines, lineno),
52
+ :locals => locals_data(filename, lineno)
51
53
  }
52
54
  end
53
55
 
@@ -94,6 +96,12 @@ module Rollbar
94
96
  }
95
97
  end
96
98
 
99
+ def locals_data(filename, lineno)
100
+ return unless configuration.locals[:enabled]
101
+
102
+ ::Rollbar::Item::Locals.locals_for_location(filename, lineno)
103
+ end
104
+
97
105
  def post_data(file_lines, lineno)
98
106
  from_line = lineno
99
107
  number_of_lines = [from_line + MAX_CONTEXT_LENGTH, file_lines.size].min - from_line
@@ -0,0 +1,100 @@
1
+ require 'rollbar/notifier'
2
+ require 'rollbar/scrubbers/params'
3
+ require 'rollbar/util'
4
+
5
+ module Rollbar
6
+ class Item
7
+ class Locals # :nodoc:
8
+ class << self
9
+ def exception_frames
10
+ Rollbar.notifier.exception_bindings
11
+ end
12
+
13
+ def locals_for_location(filename, lineno)
14
+ if (frame = frame_for_location(filename, lineno))
15
+ scrub(locals_for(frame[:binding]))
16
+ else
17
+ {}
18
+ end
19
+ end
20
+
21
+ def frame_for_location(filename, lineno)
22
+ while (frame = exception_frames.pop)
23
+ return nil unless frame
24
+ return frame if matching_frame?(frame, filename, lineno)
25
+ end
26
+ nil
27
+ end
28
+
29
+ private
30
+
31
+ def matching_frame?(frame, filename, lineno)
32
+ frame[:path] == filename && frame[:lineno].to_i <= lineno.to_i
33
+ end
34
+
35
+ def locals_for(frame)
36
+ {}.tap do |hash|
37
+ frame.local_variables.map do |var|
38
+ hash[var] = prepare_value(frame.local_variable_get(var))
39
+ end
40
+ end
41
+ end
42
+
43
+ # Prepare objects to be handled by the payload serializer.
44
+ #
45
+ # Hashes and Arrays are traversed. Then all types execpt strings and
46
+ # immediates are exported using #inspect. Sending the object itself to the
47
+ # serializer can result in large recursive expansions, especially in Rails
48
+ # environments with ActiveRecord, ActiveSupport, etc. on the stack.
49
+ # Other export options could be #to_s, #to_h, and #as_json. Several of these
50
+ # will omit the class name, or are not implemented for many types.
51
+ #
52
+ # #inspect has the advantage that it is specifically intended for debugging
53
+ # output. If the user wants more or different information in the payload
54
+ # about a specific type, #inspect is the correct place to implement it.
55
+ # Likewise the default implementation should be oriented toward usefulness
56
+ # in debugging.
57
+ #
58
+ # Because #inspect outputs a string, it can be handled well by the string
59
+ # truncation strategy for large payloads.
60
+ #
61
+ def prepare_value(value)
62
+ return simple_value?(value) ? value : value.inspect unless value.is_a?(Hash) || value.is_a?(Array)
63
+
64
+ cloned_value = ::Rollbar::Util.deep_copy(value)
65
+ ::Rollbar::Util.iterate_and_update_with_block(cloned_value) do |v|
66
+ simple_value?(v) ? v : v.inspect
67
+ end
68
+
69
+ cloned_value
70
+ end
71
+
72
+ def simple_classes
73
+ if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.4.0')
74
+ [String, Symbol, Integer, Float, TrueClass, FalseClass, NilClass]
75
+ else
76
+ [String, Symbol, Fixnum, Bignum, Float, TrueClass, FalseClass, NilClass] # rubocop:disable Lint/UnifiedInteger
77
+ end
78
+ end
79
+
80
+ def simple_value?(value)
81
+ simple_classes.each do |klass|
82
+ # Use instance_of? so that subclasses and module containers will
83
+ # be treated like complex object types, not simple values.
84
+ return true if value.instance_of?(klass)
85
+ end
86
+
87
+ false
88
+ end
89
+
90
+ def scrub(hash)
91
+ Rollbar::Scrubbers::Params.call(
92
+ :params => hash,
93
+ :config => Rollbar.configuration.scrub_fields,
94
+ :whitelist => Rollbar.configuration.scrub_whitelist
95
+ )
96
+ end
97
+ end
98
+ end
99
+ end
100
+ end
data/lib/rollbar/item.rb CHANGED
@@ -12,6 +12,7 @@ require 'rollbar/util'
12
12
  require 'rollbar/encoding'
13
13
  require 'rollbar/truncation'
14
14
  require 'rollbar/json'
15
+ require 'rollbar/scrubbers/params'
15
16
 
16
17
  module Rollbar
17
18
  # This class represents the payload to be sent to the API.
@@ -64,7 +65,6 @@ module Rollbar
64
65
  def build
65
66
  data = build_data
66
67
  self.payload = {
67
- 'access_token' => configuration.access_token,
68
68
  'data' => data
69
69
  }
70
70
 
@@ -83,7 +83,8 @@ module Rollbar
83
83
  :server => server_data,
84
84
  :notifier => {
85
85
  :name => 'rollbar-gem',
86
- :version => VERSION
86
+ :version => VERSION,
87
+ :configured_options => configured_options
87
88
  },
88
89
  :body => build_body
89
90
  }
@@ -101,29 +102,61 @@ module Rollbar
101
102
  data
102
103
  end
103
104
 
105
+ def configured_options
106
+ if Gem.loaded_specs['activesupport'] && Gem.loaded_specs['activesupport'].version < Gem::Version.new('4.1')
107
+ # There are too many types that crash ActiveSupport JSON serialization, and not worth
108
+ # the risk just to send this diagnostic object. In versions < 4.1, ActiveSupport hooks
109
+ # Ruby's JSON.generate so deeply there's no workaround.
110
+ 'not serialized in ActiveSupport < 4.1'
111
+ elsif configuration.use_async && !configuration.async_json_payload
112
+ # The setting allows serialization to be performed by each handler,
113
+ # and this usually means it is actually performed by ActiveSupport,
114
+ # which cannot safely serialize this key.
115
+ 'not serialized when async_json_payload is not set'
116
+ else
117
+ scrub(configuration.configured_options.configured)
118
+ end
119
+ end
120
+
104
121
  def dump
105
122
  # Ensure all keys are strings since we can receive the payload inline or
106
123
  # from an async handler job, which can be serialized.
107
124
  stringified_payload = Util::Hash.deep_stringify_keys(payload)
108
- result = Truncation.truncate(stringified_payload)
125
+ attempts = []
126
+ result = Truncation.truncate(stringified_payload, attempts)
109
127
 
110
128
  return result unless Truncation.truncate?(result)
111
129
 
112
- handle_too_large_payload(stringified_payload, result)
130
+ handle_too_large_payload(stringified_payload, result, attempts)
113
131
 
114
132
  nil
115
133
  end
116
134
 
117
- def handle_too_large_payload(stringified_payload, final_payload)
118
- original_size = Rollbar::JSON.dump(stringified_payload).bytesize
119
- final_size = final_payload.bytesize
135
+ def handle_too_large_payload(stringified_payload, final_payload, attempts)
120
136
  uuid = stringified_payload['data']['uuid']
121
137
  host = stringified_payload['data'].fetch('server', {})['host']
122
138
 
123
- notifier.send_failsafe("Could not send payload due to it being too large after truncating attempts. Original size: #{original_size} Final size: #{final_size}", nil, uuid, host)
139
+ original_error = {
140
+ :message => message,
141
+ :exception => exception,
142
+ :configuration => configuration,
143
+ :uuid => uuid,
144
+ :host => host
145
+ }
146
+
147
+ notifier.send_failsafe(
148
+ too_large_payload_string(attempts),
149
+ nil,
150
+ original_error
151
+ )
124
152
  logger.error("[Rollbar] Payload too large to be sent for UUID #{uuid}: #{Rollbar::JSON.dump(payload)}")
125
153
  end
126
154
 
155
+ def too_large_payload_string(attempts)
156
+ 'Could not send payload due to it being too large after truncating attempts. ' \
157
+ "Original size: #{attempts.first} Attempts: #{attempts.join(', ')} Final size: #{attempts.last}"
158
+ end
159
+
127
160
  def ignored?
128
161
  data = payload['data']
129
162
 
@@ -156,13 +189,19 @@ module Rollbar
156
189
  end
157
190
 
158
191
  def build_extra
192
+ merged_extra = Util.deep_merge(scrub(extra), scrub(error_context))
193
+
159
194
  if custom_data_method? && !Rollbar::Util.method_in_stack(:custom_data, __FILE__)
160
- Util.deep_merge(scrub(custom_data), scrub(extra) || {})
195
+ Util.deep_merge(scrub(custom_data), merged_extra)
161
196
  else
162
- scrub(extra)
197
+ merged_extra.empty? ? nil : merged_extra # avoid putting an empty {} in the payload.
163
198
  end
164
199
  end
165
200
 
201
+ def error_context
202
+ exception.respond_to?(:rollbar_context) && exception.rollbar_context
203
+ end
204
+
166
205
  def scrub(data)
167
206
  return data unless data.is_a? Hash
168
207
 
@@ -179,14 +218,14 @@ module Rollbar
179
218
  end
180
219
 
181
220
  def custom_data
182
- if configuration.custom_data_method.arity == 3
183
- data = configuration.custom_data_method.call(message, exception, context)
184
- else
185
- data = configuration.custom_data_method.call
186
- end
221
+ data = if configuration.custom_data_method.arity == 3
222
+ configuration.custom_data_method.call(message, exception, context)
223
+ else
224
+ configuration.custom_data_method.call
225
+ end
187
226
 
188
227
  Rollbar::Util.deep_copy(data)
189
- rescue => e
228
+ rescue StandardError => e
190
229
  return {} if configuration.safely?
191
230
 
192
231
  report_custom_data_error(e)
@@ -231,7 +270,7 @@ module Rollbar
231
270
  handlers.each do |handler|
232
271
  begin
233
272
  handler.call(transform_options)
234
- rescue => e
273
+ rescue StandardError => e
235
274
  logger.error("[Rollbar] Error calling the `transform` hook: #{e}")
236
275
 
237
276
  break
data/lib/rollbar/json.rb CHANGED
@@ -1,65 +1,20 @@
1
- require 'multi_json'
2
- require 'rollbar/json/oj'
3
- require 'rollbar/json/default'
4
1
  require 'rollbar/language_support'
5
-
6
- begin
7
- require 'oj'
8
- rescue LoadError
9
- end
2
+ require 'json'
10
3
 
11
4
  module Rollbar
12
- module JSON
5
+ module JSON # :nodoc:
13
6
  extend self
14
7
 
15
8
  attr_writer :options_module
16
9
 
17
10
  def dump(object)
18
- with_adapter { MultiJson.dump(object, adapter_options) }
19
- end
20
-
21
- def load(string)
22
- with_adapter { MultiJson.load(string, adapter_options) }
23
- end
24
-
25
- def with_adapter(&block)
26
- MultiJson.with_adapter(detect_multi_json_adapter, &block)
27
- end
28
-
29
- def detect_multi_json_adapter
30
- options = {}
31
- options[:adapter] = :oj if defined?(::Oj)
32
-
33
- MultiJson.current_adapter(options)
34
- end
35
-
36
- def adapter_options
37
- options_module.options
38
- end
39
-
40
- def options_module
41
- @options_module ||= find_options_module
42
- end
43
-
44
- def find_options_module
45
- module_name = multi_json_adapter_module_name
46
-
47
- if LanguageSupport.const_defined?(Rollbar::JSON, module_name, false)
48
- LanguageSupport.const_get(Rollbar::JSON, module_name, false)
49
- else
50
- Default
11
+ Rollbar.plugins.get('basic_socket').load_scoped!(true) do
12
+ ::JSON.generate(object)
51
13
  end
52
14
  end
53
15
 
54
- # MultiJson adapters have this name structure:
55
- # "MultiJson::Adapters::{AdapterModule}"
56
- #
57
- # Ex: MultiJson::Adapters::Oj
58
- # Ex: MultiJson::Adapters::JsonGem
59
- #
60
- # In this method we just get the last module name.
61
- def multi_json_adapter_module_name
62
- detect_multi_json_adapter.name[/^MultiJson::Adapters::(.*)$/, 1]
16
+ def load(string)
17
+ ::JSON.parse(string)
63
18
  end
64
19
  end
65
20
  end
@@ -1,29 +1,13 @@
1
1
  module Rollbar
2
2
  module LanguageSupport
3
- extend self
3
+ module_function
4
4
 
5
5
  def const_defined?(mod, target, inherit = true)
6
- if ruby_18?
7
- mod.const_defined?(target)
8
- else
9
- mod.const_defined?(target, inherit)
10
- end
6
+ mod.const_defined?(target, inherit)
11
7
  end
12
8
 
13
9
  def const_get(mod, target, inherit = true)
14
- if ruby_18?
15
- mod.const_get(target)
16
- else
17
- mod.const_get(target, inherit)
18
- end
19
- end
20
-
21
- def can_scrub_url?
22
- !version?('1.8')
23
- end
24
-
25
- def ruby_18?
26
- version?('1.8')
10
+ mod.const_get(target, inherit)
27
11
  end
28
12
 
29
13
  def ruby_19?
@@ -37,7 +21,7 @@ module Rollbar
37
21
  end
38
22
 
39
23
  def timeout_exceptions
40
- return [] if ruby_18? || ruby_19?
24
+ return [] if ruby_19?
41
25
 
42
26
  [Net::ReadTimeout, Net::OpenTimeout]
43
27
  end
@@ -21,11 +21,11 @@ module Rollbar
21
21
  end
22
22
 
23
23
  def ==(other)
24
- if other.is_a?(self.class)
25
- raw == other.raw
26
- else
27
- raw == other
28
- end
24
+ raw == if other.is_a?(self.class)
25
+ other.raw
26
+ else
27
+ other
28
+ end
29
29
  end
30
30
 
31
31
  # With this version of clone we ensure that the loaded_data is empty
@@ -67,6 +67,7 @@ module Rollbar
67
67
 
68
68
  def blank?(message)
69
69
  return message.blank? if message.respond_to?(:blank?)
70
+
70
71
  message.respond_to?(:empty?) ? !!message.empty? : !message
71
72
  end
72
73
 
@@ -26,7 +26,7 @@ module Rollbar
26
26
  return unless Rollbar.configuration.enabled && acceptable_levels.include?(level.to_sym)
27
27
 
28
28
  @object.send(level, message)
29
- rescue
29
+ rescue StandardError
30
30
  puts "[Rollbar] Error logging #{level}:"
31
31
  puts "[Rollbar] #{message}"
32
32
  end
@@ -36,7 +36,11 @@ module Rollbar
36
36
  def acceptable_levels
37
37
  @acceptable_levels ||= begin
38
38
  levels = [:debug, :info, :warn, :error]
39
- levels[levels.find_index(Rollbar.configuration.logger_level)..-1]
39
+ if Rollbar.configuration.logger_level
40
+ levels[levels.find_index(Rollbar.configuration.logger_level)..-1]
41
+ else
42
+ []
43
+ end
40
44
  end
41
45
  end
42
46
  end
@@ -13,7 +13,7 @@ module Rollbar
13
13
  attr_reader :app
14
14
  attr_reader :config
15
15
 
16
- JS_IS_INJECTED_KEY = 'rollbar.js_is_injected'
16
+ JS_IS_INJECTED_KEY = 'rollbar.js_is_injected'.freeze
17
17
  SNIPPET = File.read(File.expand_path('../../../../data/rollbar.snippet.js', __FILE__))
18
18
 
19
19
  def initialize(app, config)
@@ -29,7 +29,7 @@ module Rollbar
29
29
 
30
30
  response_string = add_js(env, app_result[2])
31
31
  build_response(env, app_result, response_string)
32
- rescue => e
32
+ rescue StandardError => e
33
33
  Rollbar.log_error("[Rollbar] Rollbar.js could not be added because #{e} exception")
34
34
 
35
35
  app_result
@@ -71,7 +71,7 @@ module Rollbar
71
71
  return nil unless insert_after_idx
72
72
 
73
73
  build_body_with_js(env, body, insert_after_idx)
74
- rescue => e
74
+ rescue StandardError => e
75
75
  Rollbar.log_error("[Rollbar] Rollbar.js could not be added because #{e} exception")
76
76
  nil
77
77
  end
@@ -80,10 +80,18 @@ module Rollbar
80
80
  return app_result unless response_string
81
81
 
82
82
  env[JS_IS_INJECTED_KEY] = true
83
- response = ::Rack::Response.new(response_string, app_result[0],
84
- app_result[1])
85
83
 
86
- response.finish
84
+ status, headers, = app_result
85
+ headers['Content-Length'] = response_string.bytesize.to_s if headers.key?('Content-Length')
86
+
87
+ response = ::Rack::Response.new(response_string, status, headers)
88
+
89
+ finished = response.finish
90
+
91
+ # Rack < 2.x Response#finish returns self in array[2]. Rack >= 2.x returns self.body.
92
+ # Always return with the response object here regardless of rack version.
93
+ finished[2] = response
94
+ finished
87
95
  end
88
96
 
89
97
  def build_body_with_js(env, body, head_open_end)
@@ -116,6 +124,8 @@ module Rollbar
116
124
  end
117
125
 
118
126
  def config_js_tag(env)
127
+ require 'json'
128
+
119
129
  js_config = Rollbar::Util.deep_copy(config[:options])
120
130
 
121
131
  add_person_data(js_config, env)
@@ -189,17 +199,17 @@ module Rollbar
189
199
 
190
200
  secure_headers_cls = nil
191
201
 
192
- if !::SecureHeaders::respond_to?(:content_security_policy_script_nonce)
193
- secure_headers_cls = SecureHeadersFalse
194
- elsif config.respond_to?(:get)
195
- secure_headers_cls = SecureHeaders3To5
196
- elsif config.dup.respond_to?(:csp)
197
- secure_headers_cls = SecureHeaders6
198
- else
199
- secure_headers_cls = SecureHeadersFalse
200
- end
201
-
202
- secure_headers_cls.new
202
+ secure_headers_cls = if !::SecureHeaders.respond_to?(:content_security_policy_script_nonce)
203
+ SecureHeadersFalse
204
+ elsif config.respond_to?(:get)
205
+ SecureHeaders3To5
206
+ elsif config.dup.respond_to?(:csp)
207
+ SecureHeaders6
208
+ else
209
+ SecureHeadersFalse
210
+ end
211
+
212
+ secure_headers_cls.new
203
213
  end
204
214
 
205
215
  class SecureHeadersResolver
@@ -217,7 +227,7 @@ module Rollbar
217
227
  !opt_out?(csp) && !unsafe_inline?(csp)
218
228
  end
219
229
 
220
- def opt_out?(csp)
230
+ def opt_out?(_csp)
221
231
  raise NotImplementedError
222
232
  end
223
233