rollbar 2.18.2 → 2.19.0

Sign up to get free protection for your applications and to get access to all the features.
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