rollbar 2.16.2 → 2.22.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 (212) hide show
  1. checksums.yaml +5 -5
  2. data/.rubocop.yml +47 -0
  3. data/.travis.yml +182 -94
  4. data/Appraisals +10 -10
  5. data/Gemfile +45 -13
  6. data/README.md +20 -3
  7. data/Rakefile +0 -0
  8. data/data/rollbar.snippet.js +1 -1
  9. data/docs/configuration.md +15 -0
  10. data/gemfiles/rails30.gemfile +21 -14
  11. data/gemfiles/rails31.gemfile +21 -12
  12. data/gemfiles/rails32.gemfile +18 -8
  13. data/gemfiles/rails40.gemfile +18 -6
  14. data/gemfiles/rails41.gemfile +17 -6
  15. data/gemfiles/rails42.gemfile +24 -14
  16. data/gemfiles/rails50.gemfile +20 -11
  17. data/gemfiles/rails51.gemfile +20 -10
  18. data/gemfiles/rails52.gemfile +65 -0
  19. data/gemfiles/rails60.gemfile +67 -0
  20. data/lib/generators/rollbar/rollbar_generator.rb +1 -1
  21. data/lib/rails/rollbar_runner.rb +17 -2
  22. data/lib/rollbar.rb +2 -3
  23. data/lib/rollbar/capistrano.rb +71 -39
  24. data/lib/rollbar/capistrano3.rb +56 -1
  25. data/lib/rollbar/capistrano_tasks.rb +130 -0
  26. data/lib/rollbar/configuration.rb +95 -7
  27. data/lib/rollbar/delay/active_job.rb +17 -0
  28. data/lib/rollbar/delay/girl_friday.rb +2 -2
  29. data/lib/rollbar/delay/resque.rb +4 -6
  30. data/lib/rollbar/delay/shoryuken.rb +15 -9
  31. data/lib/rollbar/delay/sidekiq.rb +6 -8
  32. data/lib/rollbar/delay/sucker_punch.rb +17 -19
  33. data/lib/rollbar/delay/thread.rb +3 -3
  34. data/lib/rollbar/deploy.rb +90 -0
  35. data/lib/rollbar/encoding/encoder.rb +9 -9
  36. data/lib/rollbar/exception_reporter.rb +19 -5
  37. data/lib/rollbar/item.rb +62 -20
  38. data/lib/rollbar/item/backtrace.rb +4 -4
  39. data/lib/rollbar/item/frame.rb +7 -1
  40. data/lib/rollbar/item/locals.rb +56 -0
  41. data/lib/rollbar/json.rb +5 -51
  42. data/lib/rollbar/language_support.rb +4 -20
  43. data/lib/rollbar/lazy_store.rb +5 -5
  44. data/lib/rollbar/logger.rb +1 -0
  45. data/lib/rollbar/logger_proxy.rb +15 -2
  46. data/lib/rollbar/middleware/js.rb +110 -10
  47. data/lib/rollbar/middleware/js/json_value.rb +26 -0
  48. data/lib/rollbar/middleware/rack.rb +4 -1
  49. data/lib/rollbar/middleware/rails/rollbar.rb +10 -1
  50. data/lib/rollbar/notifier.rb +118 -49
  51. data/lib/rollbar/notifier/trace_with_bindings.rb +65 -0
  52. data/lib/rollbar/plugin.rb +54 -6
  53. data/lib/rollbar/plugins.rb +7 -1
  54. data/lib/rollbar/plugins/active_job.rb +5 -1
  55. data/lib/rollbar/plugins/basic_socket.rb +21 -6
  56. data/lib/rollbar/plugins/delayed_job/job_data.rb +3 -3
  57. data/lib/rollbar/plugins/delayed_job/plugin.rb +3 -3
  58. data/lib/rollbar/plugins/goalie.rb +11 -3
  59. data/lib/rollbar/plugins/rails/controller_methods.rb +17 -4
  60. data/lib/rollbar/plugins/rails/railtie_mixin.rb +7 -3
  61. data/lib/rollbar/plugins/rake.rb +2 -2
  62. data/lib/rollbar/plugins/sidekiq/plugin.rb +10 -6
  63. data/lib/rollbar/rake_tasks.rb +3 -86
  64. data/lib/rollbar/request_data_extractor.rb +35 -21
  65. data/lib/rollbar/rollbar_test.rb +147 -0
  66. data/lib/rollbar/scrubbers.rb +7 -3
  67. data/lib/rollbar/scrubbers/params.rb +38 -20
  68. data/lib/rollbar/scrubbers/url.rb +27 -13
  69. data/lib/rollbar/truncation.rb +9 -2
  70. data/lib/rollbar/truncation/min_body_strategy.rb +2 -3
  71. data/lib/rollbar/truncation/remove_any_key_strategy.rb +123 -0
  72. data/lib/rollbar/truncation/remove_extra_strategy.rb +35 -0
  73. data/lib/rollbar/truncation/remove_request_strategy.rb +21 -0
  74. data/lib/rollbar/truncation/strings_strategy.rb +3 -4
  75. data/lib/rollbar/util.rb +75 -45
  76. data/lib/rollbar/util/hash.rb +30 -6
  77. data/lib/rollbar/util/ip_anonymizer.rb +8 -7
  78. data/lib/rollbar/util/ip_obfuscator.rb +1 -1
  79. data/lib/rollbar/version.rb +1 -1
  80. data/lib/tasks/benchmark.rake +103 -0
  81. data/rollbar.gemspec +14 -8
  82. metadata +25 -277
  83. data/gemfiles/ruby_1_8_and_1_9_2.gemfile +0 -49
  84. data/lib/rollbar/json/default.rb +0 -11
  85. data/lib/rollbar/json/oj.rb +0 -16
  86. data/lib/rollbar/tasks/rollbar.cap +0 -47
  87. data/spec/cacert.pem +0 -3988
  88. data/spec/controllers/home_controller_spec.rb +0 -480
  89. data/spec/delay/sidekiq_spec.rb +0 -61
  90. data/spec/delay/sucker_punch_spec.rb +0 -25
  91. data/spec/delayed/backend/test.rb +0 -140
  92. data/spec/delayed/serialization/test.rb +0 -0
  93. data/spec/dummyapp/.gitignore +0 -73
  94. data/spec/dummyapp/Rakefile +0 -7
  95. data/spec/dummyapp/app/assets/javascripts/application.js +0 -3
  96. data/spec/dummyapp/app/assets/stylesheets/application.css.scss +0 -37
  97. data/spec/dummyapp/app/controllers/application_controller.rb +0 -3
  98. data/spec/dummyapp/app/controllers/home_controller.rb +0 -60
  99. data/spec/dummyapp/app/controllers/users_controller.rb +0 -17
  100. data/spec/dummyapp/app/helpers/.gitkeep +0 -0
  101. data/spec/dummyapp/app/mailers/.gitkeep +0 -0
  102. data/spec/dummyapp/app/models/.gitkeep +0 -0
  103. data/spec/dummyapp/app/models/book.rb +0 -5
  104. data/spec/dummyapp/app/models/post.rb +0 -9
  105. data/spec/dummyapp/app/models/user.rb +0 -9
  106. data/spec/dummyapp/app/views/devise/registrations/edit.html.erb +0 -27
  107. data/spec/dummyapp/app/views/devise/registrations/new.html.erb +0 -20
  108. data/spec/dummyapp/app/views/devise/shared/_links.html.erb +0 -25
  109. data/spec/dummyapp/app/views/home/cause_exception.html.erb +0 -1
  110. data/spec/dummyapp/app/views/home/index.html.erb +0 -4
  111. data/spec/dummyapp/app/views/home/report_exception.html.erb +0 -1
  112. data/spec/dummyapp/app/views/js/test.html.erb +0 -1
  113. data/spec/dummyapp/app/views/layouts/_messages.html.erb +0 -5
  114. data/spec/dummyapp/app/views/layouts/_navigation.html.erb +0 -21
  115. data/spec/dummyapp/app/views/layouts/application.html.erb +0 -25
  116. data/spec/dummyapp/app/views/layouts/simple.html.erb +0 -18
  117. data/spec/dummyapp/app/views/users/index.html.erb +0 -8
  118. data/spec/dummyapp/app/views/users/show.html.erb +0 -3
  119. data/spec/dummyapp/config.ru +0 -4
  120. data/spec/dummyapp/config/application.rb +0 -59
  121. data/spec/dummyapp/config/boot.rb +0 -10
  122. data/spec/dummyapp/config/database.yml +0 -25
  123. data/spec/dummyapp/config/environment.rb +0 -5
  124. data/spec/dummyapp/config/environments/development.rb +0 -37
  125. data/spec/dummyapp/config/environments/production.rb +0 -67
  126. data/spec/dummyapp/config/environments/test.rb +0 -37
  127. data/spec/dummyapp/config/initializers/backtrace_silencers.rb +0 -7
  128. data/spec/dummyapp/config/initializers/inflections.rb +0 -15
  129. data/spec/dummyapp/config/initializers/mime_types.rb +0 -5
  130. data/spec/dummyapp/config/initializers/rollbar.rb +0 -26
  131. data/spec/dummyapp/config/initializers/secret_token.rb +0 -7
  132. data/spec/dummyapp/config/initializers/session_store.rb +0 -8
  133. data/spec/dummyapp/config/initializers/wrap_parameters.rb +0 -16
  134. data/spec/dummyapp/config/locales/devise.en.yml +0 -58
  135. data/spec/dummyapp/config/locales/en.yml +0 -5
  136. data/spec/dummyapp/config/routes.rb +0 -17
  137. data/spec/dummyapp/config/secrets.yml +0 -2
  138. data/spec/dummyapp/db/migrate/20121121184652_devise_create_users.rb +0 -46
  139. data/spec/dummyapp/db/migrate/20121121184654_add_name_to_users.rb +0 -5
  140. data/spec/dummyapp/db/migrate/20161219184410_create_books.rb +0 -10
  141. data/spec/dummyapp/db/migrate/20161219185529_add_username_to_users.rb +0 -5
  142. data/spec/dummyapp/db/schema.rb +0 -41
  143. data/spec/dummyapp/db/seeds.rb +0 -12
  144. data/spec/dummyapp/lib/assets/.gitkeep +0 -0
  145. data/spec/dummyapp/public/404.html +0 -26
  146. data/spec/dummyapp/public/422.html +0 -26
  147. data/spec/dummyapp/public/500.html +0 -25
  148. data/spec/dummyapp/public/favicon.ico +0 -0
  149. data/spec/dummyapp/script/rails +0 -6
  150. data/spec/fixtures/file1 +0 -1
  151. data/spec/fixtures/file2 +0 -1
  152. data/spec/fixtures/payloads/message.json +0 -25
  153. data/spec/fixtures/payloads/sample.trace.json +0 -275
  154. data/spec/fixtures/payloads/sample.trace_chain.json +0 -530
  155. data/spec/fixtures/plugins/dummy1.rb +0 -5
  156. data/spec/fixtures/plugins/dummy2.rb +0 -5
  157. data/spec/generators/rollbar/rollbar_generator_rails30_spec.rb +0 -31
  158. data/spec/generators/rollbar/rollbar_generator_spec.rb +0 -51
  159. data/spec/requests/home_spec.rb +0 -49
  160. data/spec/rollbar/configuration_spec.rb +0 -46
  161. data/spec/rollbar/delay/delayed_job_spec.rb +0 -22
  162. data/spec/rollbar/delay/girl_friday_spec.rb +0 -41
  163. data/spec/rollbar/delay/resque_spec.rb +0 -37
  164. data/spec/rollbar/delay/thread_spec.rb +0 -27
  165. data/spec/rollbar/encoding/encoder_spec.rb +0 -63
  166. data/spec/rollbar/item/backtrace_spec.rb +0 -26
  167. data/spec/rollbar/item/frame_spec.rb +0 -267
  168. data/spec/rollbar/item_spec.rb +0 -736
  169. data/spec/rollbar/json/oj_spec.rb +0 -18
  170. data/spec/rollbar/json_spec.rb +0 -110
  171. data/spec/rollbar/lazy_store_spec.rb +0 -99
  172. data/spec/rollbar/logger_proxy_spec.rb +0 -50
  173. data/spec/rollbar/logger_spec.rb +0 -124
  174. data/spec/rollbar/middleware/js_spec.rb +0 -421
  175. data/spec/rollbar/middleware/sinatra_spec.rb +0 -197
  176. data/spec/rollbar/notifier_spec.rb +0 -56
  177. data/spec/rollbar/plugin_spec.rb +0 -209
  178. data/spec/rollbar/plugins/active_job_spec.rb +0 -38
  179. data/spec/rollbar/plugins/delayed_job/job_data_spec.rb +0 -48
  180. data/spec/rollbar/plugins/delayed_job_spec.rb +0 -129
  181. data/spec/rollbar/plugins/rack_spec.rb +0 -152
  182. data/spec/rollbar/plugins/rails_js_spec.rb +0 -19
  183. data/spec/rollbar/plugins/rake_spec.rb +0 -34
  184. data/spec/rollbar/plugins/resque/failure_spec.rb +0 -36
  185. data/spec/rollbar/plugins/sidekiq_spec.rb +0 -171
  186. data/spec/rollbar/plugins/validations_spec.rb +0 -56
  187. data/spec/rollbar/plugins_spec.rb +0 -68
  188. data/spec/rollbar/request_data_extractor_spec.rb +0 -270
  189. data/spec/rollbar/scrubbers/params_spec.rb +0 -314
  190. data/spec/rollbar/scrubbers/url_spec.rb +0 -136
  191. data/spec/rollbar/scrubbers_spec.rb +0 -31
  192. data/spec/rollbar/sidekig/clear_scope_spec.rb +0 -19
  193. data/spec/rollbar/truncation/frames_strategy_spec.rb +0 -70
  194. data/spec/rollbar/truncation/min_body_strategy_spec.rb +0 -57
  195. data/spec/rollbar/truncation/strings_strategy_spec.rb +0 -89
  196. data/spec/rollbar/truncation_spec.rb +0 -27
  197. data/spec/rollbar/util/hash_spec.rb +0 -22
  198. data/spec/rollbar/util/ip_anonymizer_spec.rb +0 -30
  199. data/spec/rollbar/util_spec.rb +0 -80
  200. data/spec/rollbar_bc_spec.rb +0 -380
  201. data/spec/rollbar_spec.rb +0 -1667
  202. data/spec/spec_helper.rb +0 -84
  203. data/spec/support/cause_exception.rb +0 -1
  204. data/spec/support/encoding_helpers.rb +0 -8
  205. data/spec/support/encodings/iso_8859_9 +0 -1
  206. data/spec/support/fixture_helpers.rb +0 -10
  207. data/spec/support/get_ip_raising.rb +0 -7
  208. data/spec/support/helpers.rb +0 -5
  209. data/spec/support/matchers.rb +0 -23
  210. data/spec/support/notifier_helpers.rb +0 -57
  211. data/spec/support/rollbar_api.rb +0 -57
  212. data/spec/support/shared_contexts.rb +0 -12
@@ -1,736 +0,0 @@
1
- require 'spec_helper'
2
- require 'rollbar/configuration'
3
- require 'rollbar/item'
4
- require 'rollbar/lazy_store'
5
-
6
- describe Rollbar::Item do
7
- let(:notifier) { double('notifier', :safely => safely_notifier) }
8
- let(:safely_notifier) { double('safely_notifier') }
9
- let(:logger) { double }
10
- let(:configuration) do
11
- c = Rollbar::Configuration.new
12
- c.enabled = true
13
- c.access_token = 'footoken'
14
- c.root = '/foo/'
15
- c.framework = 'Rails'
16
- c
17
- end
18
- let(:level) { 'info' }
19
- let(:message) { 'message' }
20
- let(:exception) {}
21
- let(:extra) {}
22
- let(:scope) {}
23
- let(:context) {}
24
-
25
- let(:options) do
26
- {
27
- :level => level,
28
- :message => message,
29
- :exception => exception,
30
- :extra => extra,
31
- :configuration => configuration,
32
- :logger => logger,
33
- :scope => scope,
34
- :notifier => notifier,
35
- :context => context
36
- }
37
- end
38
-
39
- subject { described_class.new(options) }
40
-
41
- describe '#build' do
42
- let(:payload) { subject.build }
43
-
44
- context 'a basic payload' do
45
- let(:extra) { {:key => 'value', :hash => {:inner_key => 'inner_value'}} }
46
-
47
- it 'calls Rollbar::Util.enforce_valid_utf8' do
48
- expect(Rollbar::Util).to receive(:enforce_valid_utf8).with(kind_of(Hash))
49
-
50
- subject.build
51
- end
52
-
53
- it 'should have the correct root-level keys' do
54
- payload.keys.should match_array(['access_token', 'data'])
55
- end
56
-
57
- it 'should have the correct data keys' do
58
- payload['data'].keys.should include(:timestamp, :environment, :level, :language, :framework, :server,
59
- :notifier, :body)
60
- end
61
-
62
- it 'should have the correct notifier name and version' do
63
- payload['data'][:notifier][:name].should == 'rollbar-gem'
64
- payload['data'][:notifier][:version].should == Rollbar::VERSION
65
- end
66
-
67
- it 'should have the correct language and framework' do
68
- payload['data'][:language].should == 'ruby'
69
- payload['data'][:framework].should == configuration.framework
70
- payload['data'][:framework].should match(/^Rails/)
71
- end
72
-
73
- it 'should have the correct server keys' do
74
- payload['data'][:server].keys.should match_array([:host, :root, :pid])
75
- end
76
-
77
- it 'should have the correct level and message body' do
78
- payload['data'][:level].should == 'info'
79
- payload['data'][:body][:message][:body].should == 'message'
80
- end
81
- end
82
-
83
- it 'should merge in a new key from payload_options' do
84
- configuration.payload_options = { :some_new_key => 'some new value' }
85
-
86
- payload['data'][:some_new_key].should == 'some new value'
87
- end
88
-
89
- it 'should overwrite existing keys from payload_options' do
90
- payload_options = {
91
- :notifier => 'bad notifier',
92
- :server => { :host => 'new host', :new_server_key => 'value' }
93
- }
94
- configuration.payload_options = payload_options
95
-
96
- payload['data'][:notifier].should == 'bad notifier'
97
- payload['data'][:server][:host].should == 'new host'
98
- payload['data'][:server][:root].should_not be_nil
99
- payload['data'][:server][:new_server_key].should == 'value'
100
- end
101
-
102
- it 'should have default environment "unspecified"' do
103
- configuration.environment = nil
104
-
105
- payload['data'][:environment].should == 'unspecified'
106
- end
107
-
108
- it 'should have an overridden environment' do
109
- configuration.environment = 'overridden'
110
-
111
- payload['data'][:environment].should == 'overridden'
112
- end
113
-
114
- it 'should not have custom data under default configuration' do
115
- payload['data'][:body][:message][:extra].should be_nil
116
- end
117
-
118
- it 'should have custom message data when custom_data_method is configured' do
119
- configuration.custom_data_method = lambda { {:a => 1, :b => [2, 3, 4]} }
120
-
121
- payload['data'][:body][:message][:extra].should_not be_nil
122
- payload['data'][:body][:message][:extra][:a].should == 1
123
- payload['data'][:body][:message][:extra][:b][2].should == 4
124
- end
125
-
126
- context do
127
- let(:context) { { :controller => "ExampleController" } }
128
-
129
- it 'should have access to the context in custom_data_method' do
130
- configuration.custom_data_method = lambda do |message, exception, context|
131
- { :result => "MyApp#" + context[:controller] }
132
- end
133
-
134
- payload['data'][:body][:message][:extra].should_not be_nil
135
- payload['data'][:body][:message][:extra][:result].should == "MyApp#"+context[:controller]
136
- end
137
-
138
- it 'should not include data passed in :context if there is no custom_data_method configured' do
139
- configuration.custom_data_method = nil
140
-
141
- payload['data'][:body][:message][:extra].should be_nil
142
- end
143
-
144
- it 'should have access to the message in custom_data_method' do
145
- configuration.custom_data_method = lambda do |message, exception, context|
146
- { :result => "Transformed in custom_data_method: " + message }
147
- end
148
-
149
- payload['data'][:body][:message][:extra].should_not be_nil
150
- payload['data'][:body][:message][:extra][:result].should == "Transformed in custom_data_method: " + message
151
- end
152
-
153
- context do
154
- let(:exception) { Exception.new "Exception to test custom_data_method" }
155
-
156
- it 'should have access to the current exception in custom_data_method' do
157
- configuration.custom_data_method = lambda do |message, exception, context|
158
- { :result => "Transformed in custom_data_method: " + exception.message }
159
- end
160
-
161
- payload['data'][:body][:trace][:extra].should_not be_nil
162
- payload['data'][:body][:trace][:extra][:result].should == "Transformed in custom_data_method: " + exception.message
163
- end
164
- end
165
- end
166
-
167
- context do
168
- let(:extra) do
169
- { :c => {:e => 'g' }, :f => 'f' }
170
- end
171
-
172
- it 'should merge extra data into custom message data' do
173
- custom_method = lambda do
174
- { :a => 1,
175
- :b => [2, 3, 4],
176
- :c => { :d => 'd', :e => 'e' },
177
- :f => ['1', '2']
178
- }
179
- end
180
- configuration.custom_data_method = custom_method
181
-
182
- payload['data'][:body][:message][:extra].should_not be_nil
183
- payload['data'][:body][:message][:extra][:a].should == 1
184
- payload['data'][:body][:message][:extra][:b][2].should == 4
185
- payload['data'][:body][:message][:extra][:c][:d].should == 'd'
186
- payload['data'][:body][:message][:extra][:c][:e].should == 'g'
187
- payload['data'][:body][:message][:extra][:f].should == 'f'
188
- end
189
- end
190
-
191
- context 'with custom_data_method crashing' do
192
- next unless defined?(SecureRandom) && SecureRandom.respond_to?(:uuid)
193
-
194
- let(:crashing_exception) { StandardError.new }
195
- let(:custom_method) { proc { raise crashing_exception } }
196
- let(:extra) { { :foo => :bar } }
197
- let(:custom_data_report) do
198
- { :_error_in_custom_data_method => SecureRandom.uuid }
199
- end
200
- let(:expected_extra) { extra.merge(custom_data_report) }
201
-
202
- before do
203
- configuration.custom_data_method = custom_method
204
- end
205
-
206
- it 'doesnt crash the report' do
207
- expect(subject).to receive(:report_custom_data_error).once.and_return(custom_data_report)
208
-
209
- expect(payload['data'][:body][:message][:extra]).to be_eql(expected_extra)
210
- end
211
-
212
- context 'and for some reason the safely.error returns a String' do
213
- it 'returns an empty Hash' do
214
- allow(safely_notifier).to receive(:error).and_return('ignored')
215
-
216
- expect(payload['data'][:body][:message][:extra]).to be_eql(extra)
217
- end
218
- end
219
- end
220
-
221
- it 'should include project_gem_paths' do
222
- gems = Gem::Specification.map(&:name)
223
- project_gems = ['rails']
224
- project_gems << 'rspec' if gems.include?('rspec')
225
- project_gems << 'rspec-core' if gems.include?('rspec-core')
226
-
227
- configuration.project_gems = project_gems
228
-
229
- expect(payload['data'][:project_package_paths].count).to eq(project_gems.size)
230
- end
231
-
232
- it 'should include a code_version' do
233
- configuration.code_version = 'abcdef'
234
-
235
- payload['data'][:code_version].should == 'abcdef'
236
- end
237
-
238
- it 'should have the right hostname' do
239
- payload['data'][:server][:host].should == Socket.gethostname
240
- end
241
-
242
- it 'should have root and branch set when configured' do
243
- configuration.root = '/path/to/root'
244
- configuration.branch = 'master'
245
-
246
- payload['data'][:server][:root].should == '/path/to/root'
247
- payload['data'][:server][:branch].should == 'master'
248
- end
249
-
250
- context 'build_payload_body' do
251
- let(:exception) do
252
- begin
253
- foo = bar
254
- rescue => e
255
- e
256
- end
257
- end
258
-
259
- context 'with no exception' do
260
- let(:exception) { nil }
261
-
262
- it 'should build a message body when no exception is passed in' do
263
- payload['data'][:body][:message][:body].should == 'message'
264
- payload['data'][:body][:message][:extra].should be_nil
265
- payload['data'][:body][:trace].should be_nil
266
- end
267
-
268
- context 'and extra data' do
269
- let(:extra) do
270
- {:a => 'b'}
271
- end
272
-
273
- it 'should build a message body when no exception and extra data is passed in' do
274
- payload['data'][:body][:message][:body].should == 'message'
275
- payload['data'][:body][:message][:extra].should == {:a => 'b'}
276
- payload['data'][:body][:trace].should be_nil
277
- end
278
- end
279
- end
280
-
281
- it 'should build an exception body when one is passed in' do
282
- body = payload['data'][:body]
283
- body[:message].should be_nil
284
-
285
- trace = body[:trace]
286
- trace.should_not be_nil
287
- trace[:extra].should be_nil
288
-
289
- trace[:exception][:class].should_not be_nil
290
- trace[:exception][:message].should_not be_nil
291
- end
292
-
293
- context 'with extra data' do
294
- let(:extra) do
295
- {:a => 'b'}
296
- end
297
-
298
- it 'should build an exception body when one is passed in along with extra data' do
299
- body = payload['data'][:body]
300
- body[:message].should be_nil
301
-
302
- trace = body[:trace]
303
- trace.should_not be_nil
304
-
305
- trace[:exception][:class].should_not be_nil
306
- trace[:exception][:message].should_not be_nil
307
- trace[:extra].should == {:a => 'b'}
308
- end
309
- end
310
- end
311
-
312
- context 'build_payload_body_exception' do
313
- let(:exception) do
314
- begin
315
- foo = bar
316
- rescue => e
317
- e
318
- end
319
- end
320
-
321
- it 'should build valid exception data' do
322
- body = payload['data'][:body]
323
- body[:message].should be_nil
324
-
325
- trace = body[:trace]
326
-
327
- frames = trace[:frames]
328
- frames.should be_a_kind_of(Array)
329
- frames.each do |frame|
330
- frame[:filename].should be_a_kind_of(String)
331
- frame[:lineno].should be_a_kind_of(Fixnum)
332
- if frame[:method]
333
- frame[:method].should be_a_kind_of(String)
334
- end
335
- end
336
-
337
- # should be NameError, but can be NoMethodError sometimes on rubinius 1.8
338
- # http://yehudakatz.com/2010/01/02/the-craziest-fing-bug-ive-ever-seen/
339
- trace[:exception][:class].should match(/^(NameError|NoMethodError)$/)
340
- trace[:exception][:message].should match(/^(undefined local variable or method `bar'|undefined method `bar' on an instance of)/)
341
- end
342
-
343
- context 'with description message' do
344
- let(:message) { 'exception description' }
345
-
346
- it 'should build exception data with a description' do
347
- body = payload['data'][:body]
348
-
349
- trace = body[:trace]
350
-
351
- trace[:exception][:message].should match(/^(undefined local variable or method `bar'|undefined method `bar' on an instance of)/)
352
- trace[:exception][:description].should == 'exception description'
353
- end
354
-
355
- context 'and extra data' do
356
- let(:extra) do
357
- {:key => 'value', :hash => {:inner_key => 'inner_value'}}
358
- end
359
-
360
- it 'should build exception data with a description and extra data' do
361
- body = payload['data'][:body]
362
- trace = body[:trace]
363
-
364
- trace[:exception][:message].should match(/^(undefined local variable or method `bar'|undefined method `bar' on an instance of)/)
365
- trace[:exception][:description].should == 'exception description'
366
- trace[:extra][:key].should == 'value'
367
- trace[:extra][:hash].should == {:inner_key => 'inner_value'}
368
- end
369
- end
370
- end
371
-
372
- context 'with extra data' do
373
- let(:extra) do
374
- {:key => 'value', :hash => {:inner_key => 'inner_value'}}
375
- end
376
- it 'should build exception data with a extra data' do
377
- body = payload['data'][:body]
378
- trace = body[:trace]
379
-
380
- trace[:exception][:message].should match(/^(undefined local variable or method `bar'|undefined method `bar' on an instance of)/)
381
- trace[:extra][:key].should == 'value'
382
- trace[:extra][:hash].should == {:inner_key => 'inner_value'}
383
- end
384
- end
385
-
386
- context 'with nested exceptions' do
387
- let(:crashing_code) do
388
- proc do
389
- begin
390
- begin
391
- fail CauseException.new('the cause')
392
- rescue
393
- fail StandardError.new('the error')
394
- end
395
- rescue => e
396
- e
397
- end
398
- end
399
- end
400
-
401
- let(:exception) { crashing_code.call }
402
- let(:message) { 'message' }
403
- let(:extra) { {} }
404
-
405
- context 'using ruby >= 2.1' do
406
- next unless Exception.instance_methods.include?(:cause)
407
-
408
- it 'sends the two exceptions in the trace_chain attribute' do
409
- body = payload['data'][:body]
410
-
411
- body[:trace].should be_nil
412
- body[:trace_chain].should be_kind_of(Array)
413
-
414
- chain = body[:trace_chain]
415
- chain[0][:exception][:class].should match(/StandardError/)
416
- chain[0][:exception][:message].should match(/the error/)
417
-
418
- chain[1][:exception][:class].should match(/CauseException/)
419
- chain[1][:exception][:message].should match(/the cause/)
420
- end
421
-
422
- context 'when cause is not an Exception' do
423
- let(:exception) { Exception.new('custom cause') }
424
-
425
- it 'ignores the cause when it is not an Exception' do
426
- allow(exception).to receive(:cause) { "Foo" }
427
-
428
- payload['data'][:body][:trace].should_not be_nil
429
- end
430
- end
431
-
432
- context 'with cyclic nested exceptions' do
433
- let(:exception1) { Exception.new('exception1') }
434
- let(:exception2) { Exception.new('exception2') }
435
- let(:exception) { exception1 }
436
-
437
- before do
438
- allow(exception1).to receive(:cause).and_return(exception2)
439
- allow(exception2).to receive(:cause).and_return(exception1)
440
- end
441
-
442
- it 'doesnt loop for ever' do
443
- chain = payload['data'][:body][:trace_chain]
444
-
445
- expect(chain[0][:exception][:message]).to be_eql('exception1')
446
- expect(chain[1][:exception][:message]).to be_eql('exception2')
447
- end
448
- end
449
- end
450
-
451
- context 'using ruby <= 2.1' do
452
- next if Exception.instance_methods.include?(:cause)
453
-
454
- it 'sends only the last exception in the trace attribute' do
455
- body = payload['data'][:body]
456
-
457
- body[:trace].should be_kind_of(Hash)
458
- body[:trace_chain].should be_nil
459
-
460
- body[:trace][:exception][:class].should match(/StandardError/)
461
- body[:trace][:exception][:message].should match(/the error/)
462
- end
463
- end
464
- end
465
- end
466
-
467
- context 'build_payload_body_message' do
468
- it 'should build a message' do
469
- payload['data'][:body][:message][:body].should == 'message'
470
- payload['data'][:body][:trace].should be_nil
471
- end
472
-
473
- context 'with extra data' do
474
- let(:extra) do
475
- {:key => 'value', :hash => {:inner_key => 'inner_value'}}
476
- end
477
-
478
- it 'should build a message with extra data' do
479
- payload['data'][:body][:message][:body].should == 'message'
480
- payload['data'][:body][:message][:extra][:key].should == 'value'
481
- payload['data'][:body][:message][:extra][:hash].should == {:inner_key => 'inner_value'}
482
- end
483
- end
484
-
485
- context 'with empty message and extra data' do
486
- let(:message) { nil }
487
- let(:extra) do
488
- {:key => 'value', :hash => {:inner_key => 'inner_value'}}
489
- end
490
-
491
- it 'should build an empty message with extra data' do
492
- payload['data'][:body][:message][:body].should == 'Empty message'
493
- payload['data'][:body][:message][:extra][:key].should == 'value'
494
- payload['data'][:body][:message][:extra][:hash].should == {:inner_key => 'inner_value'}
495
- end
496
- end
497
- end
498
-
499
- context 'with transform handlers in configuration' do
500
- let(:scope) { Rollbar::LazyStore.new({ :bar => :foo }) }
501
- let(:message) { 'message' }
502
- let(:exception) { Exception.new }
503
- let(:extra) { { :foo => :bar } }
504
- let(:level) { 'error' }
505
-
506
- context 'without mutation in payload' do
507
- let(:handler) do
508
- proc do |options|
509
-
510
- end
511
- end
512
-
513
- before do
514
- configuration.transform = handler
515
- end
516
-
517
- it 'calls the handler with the correct options' do
518
- options = {
519
- :level => subject.level,
520
- :scope => subject.scope,
521
- :exception => subject.exception,
522
- :message => subject.message,
523
- :extra => subject.extra,
524
- :payload => kind_of(Hash)
525
- }
526
-
527
- expect(handler).to receive(:call).with(options).and_call_original
528
-
529
- subject.build
530
- end
531
- end
532
-
533
- context 'with mutation in payload' do
534
- let(:new_payload) do
535
- {
536
- 'access_token' => configuration.access_token,
537
- 'data' => {
538
- }
539
- }
540
- end
541
- let(:handler) do
542
- proc do |options|
543
- payload = options[:payload]
544
-
545
- payload.replace(new_payload)
546
- end
547
- end
548
-
549
- before do
550
- configuration.transform = handler
551
- end
552
-
553
- it 'calls the handler with the correct options' do
554
- options = {
555
- :level => level,
556
- :scope => Rollbar::LazyStore.new(scope),
557
- :exception => exception,
558
- :message => message,
559
- :extra => extra,
560
- :payload => kind_of(Hash)
561
- }
562
- expect(handler).to receive(:call).with(options).and_call_original
563
- expect(payload).to be_eql(new_payload)
564
- end
565
- end
566
-
567
- context 'with two handlers' do
568
- let(:handler1) { proc { |options|} }
569
- let(:handler2) { proc { |options|} }
570
-
571
- before do
572
- configuration.transform << handler1
573
- configuration.transform << handler2
574
- end
575
-
576
- context 'and the first one fails' do
577
- let(:exception) { StandardError.new('foo') }
578
- let(:handler1) do
579
- proc { |options| raise exception }
580
- end
581
-
582
- it 'doesnt call the second handler and logs the error' do
583
- expect(handler2).not_to receive(:call)
584
- expect(logger).to receive(:error).with("[Rollbar] Error calling the `transform` hook: #{exception}")
585
-
586
- subject.build
587
- end
588
- end
589
- end
590
- end
591
-
592
- describe '#custom_data' do
593
- before do
594
- configuration.custom_data_method = proc { raise 'this-will-raise' }
595
-
596
- expect(safely_notifier).to receive(:error).and_return(report_data)
597
- end
598
-
599
- context 'with uuid in reported data' do
600
- next unless defined?(SecureRandom) and SecureRandom.respond_to?(:uuid)
601
-
602
- let(:report_data) { { :uuid => SecureRandom.uuid } }
603
- let(:expected_url) { "https://rollbar.com/instance/uuid?uuid=#{report_data[:uuid]}" }
604
-
605
- it 'returns the uuid in :_error_in_custom_data_method' do
606
- expect(payload['data'][:body][:message][:extra]).to be_eql(:_error_in_custom_data_method => expected_url)
607
- end
608
- end
609
-
610
- context 'without uuid in reported data' do
611
- let(:report_data) { { :some => 'other-data' } }
612
-
613
- it 'returns empty data' do
614
- expect(payload['data'][:body][:message][:extra]).to be_eql({})
615
- end
616
- end
617
- end
618
-
619
- context 'server_data' do
620
- it 'should have the right hostname' do
621
- payload['data'][:server][:host] == Socket.gethostname
622
- end
623
-
624
- it 'should have root and branch set when configured' do
625
- configuration.root = '/path/to/root'
626
- configuration.branch = 'master'
627
-
628
- payload['data'][:server][:root].should == '/path/to/root'
629
- payload['data'][:server][:branch].should == 'master'
630
- end
631
-
632
- context 'with custom hostname' do
633
- before do
634
- configuration.host = host
635
- end
636
-
637
- let(:host) { 'my-custom-hostname' }
638
-
639
- it 'sends the custom hostname' do
640
- expect(payload['data'][:server][:host]).to be_eql(host)
641
- end
642
- end
643
- end
644
-
645
- context 'with ignored person ids' do
646
- let(:ignored_ids) { [1,2,4] }
647
- let(:person_data) do
648
- { :person => {
649
- :id => 2,
650
- :username => 'foo'
651
- }
652
- }
653
- end
654
- let(:scope) { Rollbar::LazyStore.new(person_data) }
655
-
656
- before do
657
- configuration.person_id_method = :id
658
- configuration.ignored_person_ids = ignored_ids
659
- end
660
-
661
- it 'sets ignored property to true' do
662
- subject.build
663
-
664
- expect(subject).to be_ignored
665
- end
666
- end
667
-
668
- end # end #build
669
-
670
- describe '#dump' do
671
- context 'with Redis instance in payload and ActiveSupport is enabled' do
672
- let(:redis) { ::Redis.new }
673
- let(:payload) do
674
- {
675
- :key => {
676
- :value => redis
677
- }
678
- }
679
- end
680
- let(:item) { Rollbar::Item.build_with(payload) }
681
-
682
- it 'dumps to JSON correctly' do
683
- redis.set('foo', 'bar')
684
- json = item.dump
685
-
686
- expect(json).to be_kind_of(String)
687
- end
688
- end
689
-
690
- context 'with too large payload', :fixture => :payload do
691
- let(:payload_fixture) { 'payloads/sample.trace.json' }
692
- let(:item) do
693
- Rollbar::Item.build_with(payload,
694
- :notifier => notifier,
695
- :configuration => configuration,
696
- :logger => logger)
697
- end
698
-
699
- before do
700
- allow(Rollbar::Truncation).to receive(:truncate?).and_return(true)
701
- end
702
-
703
- it 'calls Notifier#send_failsafe and logs the error' do
704
- original_size = Rollbar::JSON.dump(payload).bytesize
705
- final_size = Rollbar::Truncation.truncate(payload.clone).bytesize
706
- # final_size = original_size
707
- rollbar_message = "Could not send payload due to it being too large after truncating attempts. Original size: #{original_size} Final size: #{final_size}"
708
- uuid = payload['data']['uuid']
709
- host = payload['data']['server']['host']
710
- log_message = "[Rollbar] Payload too large to be sent for UUID #{uuid}: #{Rollbar::JSON.dump(payload)}"
711
-
712
- expect(notifier).to receive(:send_failsafe).with(rollbar_message, nil, uuid, host)
713
- expect(logger).to receive(:error).with(log_message)
714
-
715
- item.dump
716
- end
717
-
718
- context 'with missing server data' do
719
- it 'calls Notifier#send_failsafe and logs the error' do
720
- payload['data'].delete('server')
721
- original_size = Rollbar::JSON.dump(payload).bytesize
722
- final_size = Rollbar::Truncation.truncate(payload.clone).bytesize
723
- # final_size = original_size
724
- rollbar_message = "Could not send payload due to it being too large after truncating attempts. Original size: #{original_size} Final size: #{final_size}"
725
- uuid = payload['data']['uuid']
726
- log_message = "[Rollbar] Payload too large to be sent for UUID #{uuid}: #{Rollbar::JSON.dump(payload)}"
727
-
728
- expect(notifier).to receive(:send_failsafe).with(rollbar_message, nil, uuid, nil)
729
- expect(logger).to receive(:error).with(log_message)
730
-
731
- item.dump
732
- end
733
- end
734
- end
735
- end
736
- end