rollbar 2.18.2 → 2.19.0

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 (167) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +15 -0
  3. data/.travis.yml +155 -93
  4. data/Gemfile +19 -13
  5. data/README.md +12 -0
  6. data/gemfiles/rails30.gemfile +17 -10
  7. data/gemfiles/rails31.gemfile +20 -12
  8. data/gemfiles/rails32.gemfile +16 -7
  9. data/gemfiles/rails40.gemfile +16 -5
  10. data/gemfiles/rails41.gemfile +15 -5
  11. data/gemfiles/rails42.gemfile +25 -14
  12. data/gemfiles/rails50.gemfile +15 -8
  13. data/gemfiles/rails51.gemfile +15 -8
  14. data/gemfiles/rails52.gemfile +62 -0
  15. data/gemfiles/ruby_1_8_and_1_9_2.gemfile +2 -2
  16. data/lib/rails/rollbar_runner.rb +16 -1
  17. data/lib/rollbar/capistrano.rb +71 -39
  18. data/lib/rollbar/capistrano3.rb +53 -1
  19. data/lib/rollbar/capistrano_tasks.rb +131 -0
  20. data/lib/rollbar/configuration.rb +13 -4
  21. data/lib/rollbar/delay/active_job.rb +17 -0
  22. data/lib/rollbar/delay/sidekiq.rb +3 -1
  23. data/lib/rollbar/delay/thread.rb +1 -1
  24. data/lib/rollbar/deploy.rb +69 -0
  25. data/lib/rollbar/item.rb +17 -6
  26. data/lib/rollbar/middleware/js.rb +25 -3
  27. data/lib/rollbar/middleware/js/json_value.rb +26 -0
  28. data/lib/rollbar/notifier.rb +32 -13
  29. data/lib/rollbar/plugins/active_job.rb +3 -0
  30. data/lib/rollbar/plugins/rails/controller_methods.rb +2 -1
  31. data/lib/rollbar/plugins/rails/railtie_mixin.rb +7 -1
  32. data/lib/rollbar/rake_tasks.rb +126 -67
  33. data/lib/rollbar/scrubbers/params.rb +6 -0
  34. data/lib/rollbar/util.rb +75 -45
  35. data/lib/rollbar/util/hash.rb +15 -6
  36. data/lib/rollbar/version.rb +1 -1
  37. data/rollbar.gemspec +2 -3
  38. metadata +9 -261
  39. data/lib/rollbar/tasks/rollbar.cap +0 -47
  40. data/spec/cacert.pem +0 -3988
  41. data/spec/controllers/home_controller_spec.rb +0 -480
  42. data/spec/delay/sidekiq_spec.rb +0 -61
  43. data/spec/delay/sucker_punch_spec.rb +0 -25
  44. data/spec/delayed/backend/test.rb +0 -140
  45. data/spec/delayed/serialization/test.rb +0 -0
  46. data/spec/dummyapp/.gitignore +0 -73
  47. data/spec/dummyapp/Rakefile +0 -7
  48. data/spec/dummyapp/app/assets/javascripts/application.js +0 -3
  49. data/spec/dummyapp/app/assets/stylesheets/application.css.scss +0 -37
  50. data/spec/dummyapp/app/controllers/application_controller.rb +0 -3
  51. data/spec/dummyapp/app/controllers/home_controller.rb +0 -60
  52. data/spec/dummyapp/app/controllers/users_controller.rb +0 -17
  53. data/spec/dummyapp/app/helpers/.gitkeep +0 -0
  54. data/spec/dummyapp/app/mailers/.gitkeep +0 -0
  55. data/spec/dummyapp/app/models/.gitkeep +0 -0
  56. data/spec/dummyapp/app/models/book.rb +0 -5
  57. data/spec/dummyapp/app/models/post.rb +0 -9
  58. data/spec/dummyapp/app/models/user.rb +0 -9
  59. data/spec/dummyapp/app/views/devise/registrations/edit.html.erb +0 -27
  60. data/spec/dummyapp/app/views/devise/registrations/new.html.erb +0 -20
  61. data/spec/dummyapp/app/views/devise/shared/_links.html.erb +0 -25
  62. data/spec/dummyapp/app/views/home/cause_exception.html.erb +0 -1
  63. data/spec/dummyapp/app/views/home/index.html.erb +0 -4
  64. data/spec/dummyapp/app/views/home/report_exception.html.erb +0 -1
  65. data/spec/dummyapp/app/views/js/test.html.erb +0 -1
  66. data/spec/dummyapp/app/views/layouts/_messages.html.erb +0 -5
  67. data/spec/dummyapp/app/views/layouts/_navigation.html.erb +0 -21
  68. data/spec/dummyapp/app/views/layouts/application.html.erb +0 -25
  69. data/spec/dummyapp/app/views/layouts/simple.html.erb +0 -18
  70. data/spec/dummyapp/app/views/users/index.html.erb +0 -8
  71. data/spec/dummyapp/app/views/users/show.html.erb +0 -3
  72. data/spec/dummyapp/config.ru +0 -4
  73. data/spec/dummyapp/config/application.rb +0 -59
  74. data/spec/dummyapp/config/boot.rb +0 -10
  75. data/spec/dummyapp/config/database.yml +0 -25
  76. data/spec/dummyapp/config/environment.rb +0 -5
  77. data/spec/dummyapp/config/environments/development.rb +0 -37
  78. data/spec/dummyapp/config/environments/production.rb +0 -67
  79. data/spec/dummyapp/config/environments/test.rb +0 -37
  80. data/spec/dummyapp/config/initializers/backtrace_silencers.rb +0 -7
  81. data/spec/dummyapp/config/initializers/inflections.rb +0 -15
  82. data/spec/dummyapp/config/initializers/mime_types.rb +0 -5
  83. data/spec/dummyapp/config/initializers/rollbar.rb +0 -26
  84. data/spec/dummyapp/config/initializers/secret_token.rb +0 -7
  85. data/spec/dummyapp/config/initializers/session_store.rb +0 -8
  86. data/spec/dummyapp/config/initializers/wrap_parameters.rb +0 -16
  87. data/spec/dummyapp/config/locales/devise.en.yml +0 -58
  88. data/spec/dummyapp/config/locales/en.yml +0 -5
  89. data/spec/dummyapp/config/routes.rb +0 -17
  90. data/spec/dummyapp/config/secrets.yml +0 -2
  91. data/spec/dummyapp/db/migrate/20121121184652_devise_create_users.rb +0 -46
  92. data/spec/dummyapp/db/migrate/20121121184654_add_name_to_users.rb +0 -5
  93. data/spec/dummyapp/db/migrate/20161219184410_create_books.rb +0 -10
  94. data/spec/dummyapp/db/migrate/20161219185529_add_username_to_users.rb +0 -5
  95. data/spec/dummyapp/db/schema.rb +0 -41
  96. data/spec/dummyapp/db/seeds.rb +0 -12
  97. data/spec/dummyapp/lib/assets/.gitkeep +0 -0
  98. data/spec/dummyapp/public/404.html +0 -26
  99. data/spec/dummyapp/public/422.html +0 -26
  100. data/spec/dummyapp/public/500.html +0 -25
  101. data/spec/dummyapp/public/favicon.ico +0 -0
  102. data/spec/dummyapp/script/rails +0 -6
  103. data/spec/fixtures/file1 +0 -1
  104. data/spec/fixtures/file2 +0 -1
  105. data/spec/fixtures/payloads/message.json +0 -25
  106. data/spec/fixtures/payloads/sample.trace.json +0 -275
  107. data/spec/fixtures/payloads/sample.trace_chain.json +0 -530
  108. data/spec/fixtures/plugins/dummy1.rb +0 -5
  109. data/spec/fixtures/plugins/dummy2.rb +0 -5
  110. data/spec/generators/rollbar/rollbar_generator_rails30_spec.rb +0 -31
  111. data/spec/generators/rollbar/rollbar_generator_spec.rb +0 -51
  112. data/spec/requests/home_spec.rb +0 -49
  113. data/spec/rollbar/configuration_spec.rb +0 -74
  114. data/spec/rollbar/delay/delayed_job_spec.rb +0 -22
  115. data/spec/rollbar/delay/girl_friday_spec.rb +0 -41
  116. data/spec/rollbar/delay/resque_spec.rb +0 -37
  117. data/spec/rollbar/delay/shoryuken_spec.rb +0 -44
  118. data/spec/rollbar/delay/thread_spec.rb +0 -27
  119. data/spec/rollbar/encoding/encoder_spec.rb +0 -63
  120. data/spec/rollbar/item/backtrace_spec.rb +0 -26
  121. data/spec/rollbar/item/frame_spec.rb +0 -267
  122. data/spec/rollbar/item_spec.rb +0 -736
  123. data/spec/rollbar/json/oj_spec.rb +0 -18
  124. data/spec/rollbar/json_spec.rb +0 -110
  125. data/spec/rollbar/lazy_store_spec.rb +0 -99
  126. data/spec/rollbar/logger_proxy_spec.rb +0 -69
  127. data/spec/rollbar/logger_spec.rb +0 -124
  128. data/spec/rollbar/middleware/js_spec.rb +0 -428
  129. data/spec/rollbar/middleware/sinatra_spec.rb +0 -197
  130. data/spec/rollbar/notifier_spec.rb +0 -67
  131. data/spec/rollbar/plugin_spec.rb +0 -209
  132. data/spec/rollbar/plugins/active_job_spec.rb +0 -45
  133. data/spec/rollbar/plugins/delayed_job/job_data_spec.rb +0 -48
  134. data/spec/rollbar/plugins/delayed_job_spec.rb +0 -129
  135. data/spec/rollbar/plugins/rack_spec.rb +0 -152
  136. data/spec/rollbar/plugins/rails_js_spec.rb +0 -19
  137. data/spec/rollbar/plugins/rake_spec.rb +0 -34
  138. data/spec/rollbar/plugins/resque/failure_spec.rb +0 -36
  139. data/spec/rollbar/plugins/sidekiq_spec.rb +0 -169
  140. data/spec/rollbar/plugins/validations_spec.rb +0 -56
  141. data/spec/rollbar/plugins_spec.rb +0 -68
  142. data/spec/rollbar/request_data_extractor_spec.rb +0 -321
  143. data/spec/rollbar/scrubbers/params_spec.rb +0 -598
  144. data/spec/rollbar/scrubbers/url_spec.rb +0 -240
  145. data/spec/rollbar/scrubbers_spec.rb +0 -31
  146. data/spec/rollbar/sidekig/clear_scope_spec.rb +0 -19
  147. data/spec/rollbar/truncation/frames_strategy_spec.rb +0 -70
  148. data/spec/rollbar/truncation/min_body_strategy_spec.rb +0 -57
  149. data/spec/rollbar/truncation/strings_strategy_spec.rb +0 -89
  150. data/spec/rollbar/truncation_spec.rb +0 -27
  151. data/spec/rollbar/util/hash_spec.rb +0 -22
  152. data/spec/rollbar/util/ip_anonymizer_spec.rb +0 -30
  153. data/spec/rollbar/util_spec.rb +0 -80
  154. data/spec/rollbar_bc_spec.rb +0 -380
  155. data/spec/rollbar_spec.rb +0 -1737
  156. data/spec/spec_helper.rb +0 -84
  157. data/spec/support/cause_exception.rb +0 -1
  158. data/spec/support/encoding_helpers.rb +0 -8
  159. data/spec/support/encodings/iso_8859_9 +0 -1
  160. data/spec/support/fixture_helpers.rb +0 -10
  161. data/spec/support/get_ip_raising.rb +0 -7
  162. data/spec/support/helpers.rb +0 -5
  163. data/spec/support/matchers.rb +0 -23
  164. data/spec/support/notifier_helpers.rb +0 -57
  165. data/spec/support/rollbar_api.rb +0 -57
  166. data/spec/support/secure_headers_mocks.rb +0 -83
  167. data/spec/support/shared_contexts.rb +0 -12
@@ -1,26 +0,0 @@
1
- require 'spec_helper'
2
- require 'tempfile'
3
- require 'rollbar/item/backtrace'
4
-
5
- describe Rollbar::Item::Backtrace do
6
- describe '#get_file_lines' do
7
- subject { described_class.new(exception) }
8
-
9
- let(:exception) { Exception.new }
10
- let(:file) { Tempfile.new('foo') }
11
-
12
- before do
13
- File.open(file.path, 'w') do |f|
14
- f << "foo\nbar"
15
- end
16
- end
17
-
18
- it 'returns the lines of the file' do
19
- lines = subject.get_file_lines(file.path)
20
-
21
- expect(lines.size).to be_eql(2)
22
- expect(lines[0]).to be_eql('foo')
23
- expect(lines[1]).to be_eql('bar')
24
- end
25
- end
26
- end
@@ -1,267 +0,0 @@
1
- require 'spec_helper'
2
- require 'tempfile'
3
- require 'rollbar/item/backtrace'
4
- require 'rollbar/item/frame'
5
-
6
- describe Rollbar::Item::Frame do
7
- subject { described_class.new(backtrace, frame, options) }
8
-
9
- let(:backtrace) { double('backtrace') }
10
- let(:options) { {} }
11
-
12
- describe '#to_h' do
13
- context 'with a frame that is not a valid frame' do
14
- let(:frame) { 'this frame is not valid' }
15
-
16
- it 'return an unknown frame value' do
17
- expected_result = {
18
- :filename => '<unknown>',
19
- :lineno => 0,
20
- :method => frame
21
- }
22
-
23
- result = subject.to_h
24
- expect(result).to be_eql(expected_result)
25
- end
26
- end
27
-
28
- context 'with valid frame' do
29
- let(:file) do
30
- <<-END
31
- foo1
32
- foo2
33
- foo3
34
- foo4
35
- foo5
36
- foo6
37
- foo7
38
- foo8
39
- foo9
40
- foo10
41
- foo11
42
- foo12
43
- foo13
44
- END
45
- end
46
- let(:filepath) do
47
- '/var/www/rollbar/playground/rails4.2/vendor/bundle/gems/actionpack-4.2.0/lib/action_controller/metal/implicit_render.rb'
48
- end
49
- let(:frame) do
50
- "#{filepath}:7:in `send_action'"
51
- end
52
- let(:options) do
53
- { :configuration => configuration }
54
- end
55
-
56
- before do
57
- allow(backtrace).to receive(:get_file_lines).with(filepath).and_return(file.split("\n"))
58
- end
59
-
60
- context 'with send_extra_frame_data = :none' do
61
- let(:configuration) do
62
- double('configuration',
63
- :send_extra_frame_data => :none,
64
- :root => '/var/www')
65
- end
66
-
67
- it 'just return the filename, lineno and method' do
68
- expected_result = {
69
- :filename => filepath,
70
- :lineno => 7,
71
- :method => 'send_action'
72
- }
73
-
74
- expect(subject.to_h).to be_eql(expected_result)
75
- end
76
- end
77
-
78
- context 'with send_extra_frame_data = :all' do
79
- let(:configuration) do
80
- double('configuration',
81
- :send_extra_frame_data => :all,
82
- :root => '/var/www')
83
- end
84
-
85
- it 'returns also code and context' do
86
- expected_result = {
87
- :filename => filepath,
88
- :lineno => 7,
89
- :method => 'send_action',
90
- :code => 'foo7',
91
- :context => {
92
- :pre => %w(foo3 foo4 foo5 foo6),
93
- :post => %w(foo8 foo9 foo10 foo11)
94
- }
95
- }
96
-
97
- expect(subject.to_h).to be_eql(expected_result)
98
- end
99
-
100
- context 'if there is not lines in the file' do
101
- let(:file) do
102
- ''
103
- end
104
- it 'just returns the basic data' do
105
- expected_result = {
106
- :filename => filepath,
107
- :lineno => 7,
108
- :method => 'send_action'
109
- }
110
-
111
- expect(subject.to_h).to be_eql(expected_result)
112
- end
113
- end
114
-
115
- context 'if the file couldnt be read' do
116
- before do
117
- allow(backtrace).to receive(:get_file_lines).with(filepath).and_return(nil)
118
- end
119
-
120
- it 'just returns the basic data' do
121
- expected_result = {
122
- :filename => filepath,
123
- :lineno => 7,
124
- :method => 'send_action'
125
- }
126
-
127
- expect(subject.to_h).to be_eql(expected_result)
128
- end
129
- end
130
- end
131
-
132
- context 'with send_extra_frame_data = :app' do
133
- context 'with frame outside the root' do
134
- let(:configuration) do
135
- double('configuration',
136
- :send_extra_frame_data => :app,
137
- :root => '/outside/project',
138
- :project_gem_paths => [])
139
- end
140
-
141
- it 'just returns the basic frame data' do
142
- expected_result = {
143
- :filename => filepath,
144
- :lineno => 7,
145
- :method => 'send_action'
146
- }
147
-
148
- expect(subject.to_h).to be_eql(expected_result)
149
- end
150
- end
151
-
152
- context 'with frame inside project_gem_paths' do
153
- let(:configuration) do
154
- double('configuration',
155
- :send_extra_frame_data => :app,
156
- :root => '/var/outside/',
157
- :project_gem_paths => ['/var/www/'])
158
- end
159
-
160
- it 'returns also context and code data' do
161
- expected_result = {
162
- :filename => filepath,
163
- :lineno => 7,
164
- :method => 'send_action',
165
- :code => 'foo7',
166
- :context => {
167
- :pre => %w(foo3 foo4 foo5 foo6),
168
- :post => %w(foo8 foo9 foo10 foo11)
169
- }
170
- }
171
-
172
- expect(subject.to_h).to be_eql(expected_result)
173
- end
174
- end
175
-
176
- context 'and frame inside app root' do
177
- let(:configuration) do
178
- double('configuration',
179
- :send_extra_frame_data => :app,
180
- :root => '/var/www',
181
- :project_gem_paths => [])
182
- end
183
-
184
- it 'returns also the context and code data' do
185
- expected_result = {
186
- :filename => filepath,
187
- :lineno => 7,
188
- :method => 'send_action',
189
- :code => 'foo7',
190
- :context => {
191
- :pre => %w(foo3 foo4 foo5 foo6),
192
- :post => %w(foo8 foo9 foo10 foo11)
193
- }
194
- }
195
-
196
- expect(subject.to_h).to be_eql(expected_result)
197
- end
198
-
199
- context 'but inside Gem.path' do
200
- let(:configuration) do
201
- double('configuration',
202
- :send_extra_frame_data => :app,
203
- :root => '/var/www/',
204
- :project_gem_paths => [])
205
- end
206
-
207
- before do
208
- allow(Gem).to receive(:path).and_return(['/var/www/rollbar'])
209
- end
210
-
211
- it 'just returns also the basic data' do
212
- expected_result = {
213
- :filename => filepath,
214
- :lineno => 7,
215
- :method => 'send_action'
216
- }
217
-
218
- expect(subject.to_h).to be_eql(expected_result)
219
- end
220
- end
221
-
222
- context 'having less pre lines than maximum' do
223
- let(:frame) do
224
- "#{filepath}:3:in `send_action'"
225
- end
226
-
227
- it 'returns up to 2 pre lines' do
228
- expected_result = {
229
- :filename => filepath,
230
- :lineno => 3,
231
- :method => 'send_action',
232
- :code => 'foo3',
233
- :context => {
234
- :pre => %w(foo1 foo2),
235
- :post => %w(foo4 foo5 foo6 foo7)
236
- }
237
- }
238
-
239
- expect(subject.to_h).to be_eql(expected_result)
240
- end
241
- end
242
-
243
- context 'having less post lines than maximum' do
244
- let(:frame) do
245
- "#{filepath}:11:in `send_action'"
246
- end
247
-
248
- it 'returns up to 2 post lines' do
249
- expected_result = {
250
- :filename => filepath,
251
- :lineno => 11,
252
- :method => 'send_action',
253
- :code => 'foo11',
254
- :context => {
255
- :pre => %w(foo7 foo8 foo9 foo10),
256
- :post => %w(foo12 foo13)
257
- }
258
- }
259
-
260
- expect(subject.to_h).to be_eql(expected_result)
261
- end
262
- end
263
- end
264
- end
265
- end
266
- end
267
- end
@@ -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