rollbar 1.1.0 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -1
- data/README.md +143 -71
- data/UPGRADING.md +45 -0
- data/lib/rollbar.rb +470 -374
- data/lib/rollbar/active_record_extension.rb +1 -1
- data/lib/rollbar/configuration.rb +17 -0
- data/lib/rollbar/core_ext/thread.rb +9 -0
- data/lib/rollbar/exception_reporter.rb +4 -5
- data/lib/rollbar/logger_proxy.rb +32 -0
- data/lib/rollbar/middleware/rack/builder.rb +22 -4
- data/lib/rollbar/middleware/rails/rollbar.rb +62 -0
- data/lib/rollbar/middleware/rails/show_exceptions.rb +3 -5
- data/lib/rollbar/middleware/sinatra.rb +21 -5
- data/lib/rollbar/railtie.rb +18 -15
- data/lib/rollbar/request_data_extractor.rb +19 -9
- data/lib/rollbar/util.rb +39 -0
- data/lib/rollbar/version.rb +1 -1
- data/spec/controllers/home_controller_spec.rb +119 -154
- data/spec/dummyapp/app/controllers/home_controller.rb +16 -6
- data/spec/dummyapp/config/routes.rb +1 -0
- data/spec/rollbar/logger_proxy_spec.rb +35 -0
- data/spec/rollbar/middleware/rack/builder_spec.rb +61 -0
- data/spec/rollbar/middleware/sinatra_spec.rb +83 -5
- data/spec/rollbar_bc_spec.rb +388 -0
- data/spec/rollbar_spec.rb +940 -430
- data/spec/spec_helper.rb +1 -0
- metadata +12 -3
- data/lib/rollbar/middleware/rails/rollbar_request_store.rb +0 -25
data/spec/rollbar_spec.rb
CHANGED
@@ -12,40 +12,786 @@ rescue LoadError
|
|
12
12
|
end
|
13
13
|
|
14
14
|
describe Rollbar do
|
15
|
+
let(:notifier) { Rollbar.notifier }
|
16
|
+
context 'Notifier' do
|
17
|
+
context 'log' do
|
18
|
+
let(:exception) do
|
19
|
+
begin
|
20
|
+
foo = bar
|
21
|
+
rescue => e
|
22
|
+
e
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
15
26
|
let(:configuration) { Rollbar.configuration }
|
16
27
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
28
|
+
it 'should report a simple message' do
|
29
|
+
expect(notifier).to receive(:report).with('error', 'test message', nil, nil)
|
30
|
+
notifier.log('error', 'test message')
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'should report a simple message with extra data' do
|
34
|
+
extra_data = {:key => 'value', :hash => {:inner_key => 'inner_value'}}
|
35
|
+
|
36
|
+
expect(notifier).to receive(:report).with('error', 'test message', nil, extra_data)
|
37
|
+
notifier.log('error', 'test message', extra_data)
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'should report an exception' do
|
41
|
+
expect(notifier).to receive(:report).with('error', nil, exception, nil)
|
42
|
+
notifier.log('error', exception)
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'should report an exception with extra data' do
|
46
|
+
extra_data = {:key => 'value', :hash => {:inner_key => 'inner_value'}}
|
47
|
+
|
48
|
+
expect(notifier).to receive(:report).with('error', nil, exception, extra_data)
|
49
|
+
notifier.log('error', exception, extra_data)
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'should report an exception with a description' do
|
53
|
+
expect(notifier).to receive(:report).with('error', 'exception description', exception, nil)
|
54
|
+
notifier.log('error', exception, 'exception description')
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'should report an exception with a description and extra data' do
|
58
|
+
extra_data = {:key => 'value', :hash => {:inner_key => 'inner_value'}}
|
59
|
+
|
60
|
+
expect(notifier).to receive(:report).with('error', 'exception description', exception, extra_data)
|
61
|
+
notifier.log('error', exception, extra_data, 'exception description')
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
context 'debug/info/warning/error/critical' do
|
66
|
+
let(:exception) do
|
67
|
+
begin
|
68
|
+
foo = bar
|
69
|
+
rescue => e
|
70
|
+
e
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
let(:extra_data) { {:key => 'value', :hash => {:inner_key => 'inner_value'}} }
|
75
|
+
|
76
|
+
it 'should report with a debug level' do
|
77
|
+
expect(notifier).to receive(:report).with('debug', nil, exception, nil)
|
78
|
+
notifier.debug(exception)
|
79
|
+
|
80
|
+
expect(notifier).to receive(:report).with('debug', 'description', exception, nil)
|
81
|
+
notifier.debug(exception, 'description')
|
82
|
+
|
83
|
+
expect(notifier).to receive(:report).with('debug', 'description', exception, extra_data)
|
84
|
+
notifier.debug(exception, 'description', extra_data)
|
85
|
+
end
|
86
|
+
|
87
|
+
it 'should report with an info level' do
|
88
|
+
expect(notifier).to receive(:report).with('info', nil, exception, nil)
|
89
|
+
notifier.info(exception)
|
90
|
+
|
91
|
+
expect(notifier).to receive(:report).with('info', 'description', exception, nil)
|
92
|
+
notifier.info(exception, 'description')
|
93
|
+
|
94
|
+
expect(notifier).to receive(:report).with('info', 'description', exception, extra_data)
|
95
|
+
notifier.info(exception, 'description', extra_data)
|
96
|
+
end
|
97
|
+
|
98
|
+
it 'should report with a warning level' do
|
99
|
+
expect(notifier).to receive(:report).with('warning', nil, exception, nil)
|
100
|
+
notifier.warning(exception)
|
101
|
+
|
102
|
+
expect(notifier).to receive(:report).with('warning', 'description', exception, nil)
|
103
|
+
notifier.warning(exception, 'description')
|
104
|
+
|
105
|
+
expect(notifier).to receive(:report).with('warning', 'description', exception, extra_data)
|
106
|
+
notifier.warning(exception, 'description', extra_data)
|
107
|
+
end
|
108
|
+
|
109
|
+
it 'should report with an error level' do
|
110
|
+
expect(notifier).to receive(:report).with('error', nil, exception, nil)
|
111
|
+
notifier.error(exception)
|
112
|
+
|
113
|
+
expect(notifier).to receive(:report).with('error', 'description', exception, nil)
|
114
|
+
notifier.error(exception, 'description')
|
115
|
+
|
116
|
+
expect(notifier).to receive(:report).with('error', 'description', exception, extra_data)
|
117
|
+
notifier.error(exception, 'description', extra_data)
|
118
|
+
end
|
119
|
+
|
120
|
+
it 'should report with a critical level' do
|
121
|
+
expect(notifier).to receive(:report).with('critical', nil, exception, nil)
|
122
|
+
notifier.critical(exception)
|
123
|
+
|
124
|
+
expect(notifier).to receive(:report).with('critical', 'description', exception, nil)
|
125
|
+
notifier.critical(exception, 'description')
|
126
|
+
|
127
|
+
expect(notifier).to receive(:report).with('critical', 'description', exception, extra_data)
|
128
|
+
notifier.critical(exception, 'description', extra_data)
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
context 'scope' do
|
133
|
+
it 'should create a new notifier object' do
|
134
|
+
notifier2 = notifier.scope
|
135
|
+
|
136
|
+
notifier2.should_not eq(notifier)
|
137
|
+
notifier2.should be_instance_of(Rollbar::Notifier)
|
138
|
+
end
|
139
|
+
|
140
|
+
it 'should create a copy of the parent notifier\'s configuration' do
|
141
|
+
notifier.configure do |config|
|
142
|
+
config.code_version = '123'
|
143
|
+
config.payload_options = {
|
144
|
+
:a => 'a',
|
145
|
+
:b => {:c => 'c'}
|
146
|
+
}
|
147
|
+
end
|
148
|
+
|
149
|
+
notifier2 = notifier.scope
|
150
|
+
|
151
|
+
notifier2.configuration.code_version.should == '123'
|
152
|
+
notifier2.configuration.should_not equal(notifier.configuration)
|
153
|
+
notifier2.configuration.payload_options.should_not equal(notifier.configuration.payload_options)
|
154
|
+
notifier2.configuration.payload_options.should == notifier.configuration.payload_options
|
155
|
+
notifier2.configuration.payload_options.should == {
|
156
|
+
:a => 'a',
|
157
|
+
:b => {:c => 'c'}
|
158
|
+
}
|
159
|
+
end
|
160
|
+
|
161
|
+
it 'should not modify any parent notifier configuration' do
|
162
|
+
configure
|
163
|
+
Rollbar.configuration.code_version.should be_nil
|
164
|
+
Rollbar.configuration.payload_options.should be_empty
|
165
|
+
|
166
|
+
notifier.configure do |config|
|
167
|
+
config.code_version = '123'
|
168
|
+
config.payload_options = {
|
169
|
+
:a => 'a',
|
170
|
+
:b => {:c => 'c'}
|
171
|
+
}
|
172
|
+
end
|
173
|
+
|
174
|
+
notifier2 = notifier.scope
|
175
|
+
|
176
|
+
notifier2.configure do |config|
|
177
|
+
config.payload_options[:c] = 'c'
|
178
|
+
end
|
179
|
+
|
180
|
+
notifier.configuration.payload_options[:c].should be_nil
|
181
|
+
|
182
|
+
notifier3 = notifier2.scope({
|
183
|
+
:b => {:c => 3, :d => 'd'}
|
184
|
+
})
|
185
|
+
|
186
|
+
notifier3.configure do |config|
|
187
|
+
config.code_version = '456'
|
188
|
+
end
|
189
|
+
|
190
|
+
notifier.configuration.code_version.should == '123'
|
191
|
+
notifier.configuration.payload_options.should == {
|
192
|
+
:a => 'a',
|
193
|
+
:b => {:c => 'c'}
|
194
|
+
}
|
195
|
+
notifier2.configuration.code_version.should == '123'
|
196
|
+
notifier2.configuration.payload_options.should == {
|
197
|
+
:a => 'a',
|
198
|
+
:b => {:c => 'c'},
|
199
|
+
:c => 'c'
|
200
|
+
}
|
201
|
+
notifier3.configuration.code_version.should == '456'
|
202
|
+
notifier3.configuration.payload_options.should == {
|
203
|
+
:a => 'a',
|
204
|
+
:b => {:c => 3, :d => 'd'},
|
205
|
+
:c => 'c'
|
206
|
+
}
|
207
|
+
|
208
|
+
Rollbar.configuration.code_version.should be_nil
|
209
|
+
Rollbar.configuration.payload_options.should be_empty
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
213
|
+
context 'report' do
|
214
|
+
let(:logger_mock) { double("Rails.logger").as_null_object }
|
215
|
+
|
216
|
+
before(:each) do
|
217
|
+
configure
|
218
|
+
Rollbar.configure do |config|
|
219
|
+
config.logger = logger_mock
|
220
|
+
end
|
221
|
+
end
|
222
|
+
|
223
|
+
after(:each) do
|
224
|
+
Rollbar.unconfigure
|
225
|
+
configure
|
226
|
+
end
|
227
|
+
|
228
|
+
it 'should reject input that doesn\'t contain an exception, message or extra data' do
|
229
|
+
expect(logger_mock).to receive(:error).with('[Rollbar] Tried to send a report with no message, exception or extra data.')
|
230
|
+
expect(notifier).not_to receive(:schedule_payload)
|
231
|
+
|
232
|
+
result = notifier.send(:report, 'info', nil, nil, nil)
|
233
|
+
result.should == 'error'
|
234
|
+
end
|
235
|
+
|
236
|
+
it 'should be ignored if the person is ignored' do
|
237
|
+
person_data = {
|
238
|
+
:id => 1,
|
239
|
+
:username => "test",
|
240
|
+
:email => "test@example.com"
|
241
|
+
}
|
242
|
+
|
243
|
+
notifier.configure do |config|
|
244
|
+
config.ignored_person_ids += [1]
|
245
|
+
config.payload_options = { :person => person_data }
|
246
|
+
end
|
247
|
+
|
248
|
+
expect(notifier).not_to receive(:schedule_payload)
|
249
|
+
|
250
|
+
result = notifier.send(:report, 'info', 'message', nil, nil)
|
251
|
+
result.should == 'ignored'
|
252
|
+
end
|
253
|
+
|
254
|
+
it 'should evaluate callables in the payload' do
|
255
|
+
notifier.should receive(:schedule_payload) do |payload|
|
256
|
+
data = payload['data']
|
257
|
+
data[:body][:message][:extra][:callable].should == 2
|
258
|
+
end
|
259
|
+
|
260
|
+
callable = proc { 1 + 1 }
|
261
|
+
notifier.send(:report, 'warning', 'message', nil, { :callable => callable })
|
262
|
+
end
|
263
|
+
end
|
264
|
+
|
265
|
+
context 'build_payload' do
|
266
|
+
after(:each) do
|
267
|
+
Rollbar.unconfigure
|
268
|
+
configure
|
269
|
+
end
|
270
|
+
|
271
|
+
context 'a basic payload' do
|
272
|
+
let(:extra_data) { {:key => 'value', :hash => {:inner_key => 'inner_value'}} }
|
273
|
+
let(:payload) { notifier.send(:build_payload, 'info', 'message', nil, extra_data) }
|
274
|
+
|
275
|
+
it 'should have the correct root-level keys' do
|
276
|
+
payload.keys.should match_array(['access_token', 'data'])
|
277
|
+
end
|
278
|
+
|
279
|
+
it 'should have the correct data keys' do
|
280
|
+
payload['data'].keys.should include(:timestamp, :environment, :level, :language, :framework, :server,
|
281
|
+
:notifier, :body)
|
282
|
+
end
|
283
|
+
|
284
|
+
it 'should have the correct notifier name and version' do
|
285
|
+
payload['data'][:notifier][:name].should == 'rollbar-gem'
|
286
|
+
payload['data'][:notifier][:version].should == Rollbar::VERSION
|
287
|
+
end
|
288
|
+
|
289
|
+
it 'should have the correct language and framework' do
|
290
|
+
payload['data'][:language].should == 'ruby'
|
291
|
+
payload['data'][:framework].should == Rollbar.configuration.framework
|
292
|
+
payload['data'][:framework].should match(/^Rails/)
|
293
|
+
end
|
294
|
+
|
295
|
+
it 'should have the correct server keys' do
|
296
|
+
payload['data'][:server].keys.should match_array([:host, :root])
|
297
|
+
end
|
298
|
+
|
299
|
+
it 'should have the correct level and message body' do
|
300
|
+
payload['data'][:level].should == 'info'
|
301
|
+
payload['data'][:body][:message][:body].should == 'message'
|
302
|
+
end
|
303
|
+
end
|
304
|
+
|
305
|
+
it 'should merge in a new key from payload_options' do
|
306
|
+
notifier.configure do |config|
|
307
|
+
config.payload_options = { :some_new_key => 'some new value' }
|
308
|
+
end
|
309
|
+
|
310
|
+
payload = notifier.send(:build_payload, 'info', 'message', nil, nil)
|
311
|
+
|
312
|
+
payload['data'][:some_new_key].should == 'some new value'
|
313
|
+
end
|
314
|
+
|
315
|
+
it 'should overwrite existing keys from payload_options' do
|
316
|
+
payload_options = {
|
317
|
+
:notifier => 'bad notifier',
|
318
|
+
:server => { :host => 'new host', :new_server_key => 'value' }
|
319
|
+
}
|
320
|
+
|
321
|
+
notifier.configure do |config|
|
322
|
+
config.payload_options = payload_options
|
323
|
+
end
|
324
|
+
|
325
|
+
payload = notifier.send(:build_payload, 'info', 'message', nil, nil)
|
326
|
+
|
327
|
+
payload['data'][:notifier].should == 'bad notifier'
|
328
|
+
payload['data'][:server][:host].should == 'new host'
|
329
|
+
payload['data'][:server][:root].should_not be_nil
|
330
|
+
payload['data'][:server][:new_server_key].should == 'value'
|
331
|
+
end
|
332
|
+
|
333
|
+
it 'should have default environment "unspecified"' do
|
334
|
+
Rollbar.unconfigure
|
335
|
+
payload = notifier.send(:build_payload, 'info', 'message', nil, nil)
|
336
|
+
payload['data'][:environment].should == 'unspecified'
|
337
|
+
end
|
338
|
+
|
339
|
+
it 'should have an overridden environment' do
|
340
|
+
Rollbar.configure do |config|
|
341
|
+
config.environment = 'overridden'
|
342
|
+
end
|
343
|
+
|
344
|
+
payload = notifier.send(:build_payload, 'info', 'message', nil, nil)
|
345
|
+
payload['data'][:environment].should == 'overridden'
|
346
|
+
end
|
347
|
+
|
348
|
+
it 'should not have custom data under default configuration' do
|
349
|
+
payload = notifier.send(:build_payload, 'info', 'message', nil, nil)
|
350
|
+
payload['data'][:body][:message][:extra].should be_nil
|
351
|
+
end
|
352
|
+
|
353
|
+
it 'should have custom message data when custom_data_method is configured' do
|
354
|
+
Rollbar.configure do |config|
|
355
|
+
config.custom_data_method = lambda { {:a => 1, :b => [2, 3, 4]} }
|
356
|
+
end
|
357
|
+
|
358
|
+
payload = notifier.send(:build_payload, 'info', 'message', nil, nil)
|
359
|
+
payload['data'][:body][:message][:extra].should_not be_nil
|
360
|
+
payload['data'][:body][:message][:extra][:a].should == 1
|
361
|
+
payload['data'][:body][:message][:extra][:b][2].should == 4
|
362
|
+
end
|
363
|
+
|
364
|
+
it 'should merge extra data into custom message data' do
|
365
|
+
custom_method = lambda do
|
366
|
+
{ :a => 1,
|
367
|
+
:b => [2, 3, 4],
|
368
|
+
:c => { :d => 'd', :e => 'e' },
|
369
|
+
:f => ['1', '2']
|
370
|
+
}
|
371
|
+
end
|
372
|
+
|
373
|
+
Rollbar.configure do |config|
|
374
|
+
config.custom_data_method = custom_method
|
375
|
+
end
|
376
|
+
|
377
|
+
payload = notifier.send(:build_payload, 'info', 'message', nil, {:c => {:e => 'g'}, :f => 'f'})
|
378
|
+
payload['data'][:body][:message][:extra].should_not be_nil
|
379
|
+
payload['data'][:body][:message][:extra][:a].should == 1
|
380
|
+
payload['data'][:body][:message][:extra][:b][2].should == 4
|
381
|
+
payload['data'][:body][:message][:extra][:c][:d].should == 'd'
|
382
|
+
payload['data'][:body][:message][:extra][:c][:e].should == 'g'
|
383
|
+
payload['data'][:body][:message][:extra][:f].should == 'f'
|
384
|
+
end
|
385
|
+
|
386
|
+
it 'should include project_gem_paths' do
|
387
|
+
notifier.configure do |config|
|
388
|
+
config.project_gems = ['rails', 'rspec']
|
389
|
+
end
|
390
|
+
|
391
|
+
payload = notifier.send(:build_payload, 'info', 'message', nil, nil)
|
392
|
+
|
393
|
+
payload['data'][:project_package_paths].should have(2).items
|
394
|
+
end
|
395
|
+
|
396
|
+
it 'should include a code_version' do
|
397
|
+
notifier.configure do |config|
|
398
|
+
config.code_version = 'abcdef'
|
399
|
+
end
|
400
|
+
|
401
|
+
payload = notifier.send(:build_payload, 'info', 'message', nil, nil)
|
402
|
+
|
403
|
+
payload['data'][:code_version].should == 'abcdef'
|
404
|
+
end
|
405
|
+
|
406
|
+
it 'should have the right hostname' do
|
407
|
+
payload = notifier.send(:build_payload, 'info', 'message', nil, nil)
|
408
|
+
|
409
|
+
payload['data'][:server][:host].should == Socket.gethostname
|
410
|
+
end
|
411
|
+
|
412
|
+
it 'should have root and branch set when configured' do
|
413
|
+
configure
|
414
|
+
Rollbar.configure do |config|
|
415
|
+
config.root = '/path/to/root'
|
416
|
+
config.branch = 'master'
|
417
|
+
end
|
418
|
+
|
419
|
+
payload = notifier.send(:build_payload, 'info', 'message', nil, nil)
|
420
|
+
|
421
|
+
payload['data'][:server][:root].should == '/path/to/root'
|
422
|
+
payload['data'][:server][:branch].should == 'master'
|
423
|
+
end
|
424
|
+
end
|
425
|
+
|
426
|
+
context 'build_payload_body' do
|
427
|
+
let(:exception) do
|
428
|
+
begin
|
429
|
+
foo = bar
|
430
|
+
rescue => e
|
431
|
+
e
|
432
|
+
end
|
433
|
+
end
|
434
|
+
|
435
|
+
it 'should build a message body when no exception is passed in' do
|
436
|
+
body = notifier.send(:build_payload_body, 'message', nil, nil)
|
437
|
+
body[:message][:body].should == 'message'
|
438
|
+
body[:message][:extra].should be_nil
|
439
|
+
body[:trace].should be_nil
|
440
|
+
end
|
441
|
+
|
442
|
+
it 'should build a message body when no exception and extra data is passed in' do
|
443
|
+
body = notifier.send(:build_payload_body, 'message', nil, {:a => 'b'})
|
444
|
+
body[:message][:body].should == 'message'
|
445
|
+
body[:message][:extra].should == {:a => 'b'}
|
446
|
+
body[:trace].should be_nil
|
447
|
+
end
|
448
|
+
|
449
|
+
it 'should build an exception body when one is passed in' do
|
450
|
+
body = notifier.send(:build_payload_body, 'message', exception, nil)
|
451
|
+
body[:message].should be_nil
|
452
|
+
|
453
|
+
trace = body[:trace]
|
454
|
+
trace.should_not be_nil
|
455
|
+
trace[:extra].should be_nil
|
456
|
+
|
457
|
+
trace[:exception][:class].should_not be_nil
|
458
|
+
trace[:exception][:message].should_not be_nil
|
459
|
+
end
|
460
|
+
|
461
|
+
it 'should build an exception body when one is passed in along with extra data' do
|
462
|
+
body = notifier.send(:build_payload_body, 'message', exception, {:a => 'b'})
|
463
|
+
body[:message].should be_nil
|
464
|
+
|
465
|
+
trace = body[:trace]
|
466
|
+
trace.should_not be_nil
|
467
|
+
|
468
|
+
trace[:exception][:class].should_not be_nil
|
469
|
+
trace[:exception][:message].should_not be_nil
|
470
|
+
trace[:extra].should == {:a => 'b'}
|
471
|
+
end
|
472
|
+
end
|
473
|
+
|
474
|
+
context 'build_payload_body_exception' do
|
475
|
+
let(:exception) do
|
476
|
+
begin
|
477
|
+
foo = bar
|
478
|
+
rescue => e
|
479
|
+
e
|
480
|
+
end
|
481
|
+
end
|
482
|
+
|
483
|
+
after(:each) do
|
484
|
+
Rollbar.unconfigure
|
485
|
+
configure
|
486
|
+
end
|
487
|
+
|
488
|
+
it 'should build valid exception data' do
|
489
|
+
body = notifier.send(:build_payload_body_exception, nil, exception, nil)
|
490
|
+
body[:message].should be_nil
|
491
|
+
|
492
|
+
trace = body[:trace]
|
493
|
+
|
494
|
+
frames = trace[:frames]
|
495
|
+
frames.should be_a_kind_of(Array)
|
496
|
+
frames.each do |frame|
|
497
|
+
frame[:filename].should be_a_kind_of(String)
|
498
|
+
frame[:lineno].should be_a_kind_of(Fixnum)
|
499
|
+
if frame[:method]
|
500
|
+
frame[:method].should be_a_kind_of(String)
|
501
|
+
end
|
502
|
+
end
|
503
|
+
|
504
|
+
# should be NameError, but can be NoMethodError sometimes on rubinius 1.8
|
505
|
+
# http://yehudakatz.com/2010/01/02/the-craziest-fing-bug-ive-ever-seen/
|
506
|
+
trace[:exception][:class].should match(/^(NameError|NoMethodError)$/)
|
507
|
+
trace[:exception][:message].should match(/^(undefined local variable or method `bar'|undefined method `bar' on an instance of)/)
|
508
|
+
end
|
509
|
+
|
510
|
+
it 'should build exception data with a description' do
|
511
|
+
body = notifier.send(:build_payload_body_exception, 'exception description', exception, nil)
|
512
|
+
|
513
|
+
trace = body[:trace]
|
514
|
+
|
515
|
+
trace[:exception][:message].should match(/^(undefined local variable or method `bar'|undefined method `bar' on an instance of)/)
|
516
|
+
trace[:exception][:description].should == 'exception description'
|
517
|
+
end
|
518
|
+
|
519
|
+
it 'should build exception data with a description and extra data' do
|
520
|
+
extra_data = {:key => 'value', :hash => {:inner_key => 'inner_value'}}
|
521
|
+
body = notifier.send(:build_payload_body_exception, 'exception description', exception, extra_data)
|
522
|
+
|
523
|
+
trace = body[:trace]
|
524
|
+
|
525
|
+
trace[:exception][:message].should match(/^(undefined local variable or method `bar'|undefined method `bar' on an instance of)/)
|
526
|
+
trace[:exception][:description].should == 'exception description'
|
527
|
+
trace[:extra][:key].should == 'value'
|
528
|
+
trace[:extra][:hash].should == {:inner_key => 'inner_value'}
|
529
|
+
end
|
530
|
+
|
531
|
+
it 'should build exception data with a extra data' do
|
532
|
+
extra_data = {:key => 'value', :hash => {:inner_key => 'inner_value'}}
|
533
|
+
body = notifier.send(:build_payload_body_exception, nil, exception, extra_data)
|
534
|
+
|
535
|
+
trace = body[:trace]
|
536
|
+
|
537
|
+
trace[:exception][:message].should match(/^(undefined local variable or method `bar'|undefined method `bar' on an instance of)/)
|
538
|
+
trace[:extra][:key].should == 'value'
|
539
|
+
trace[:extra][:hash].should == {:inner_key => 'inner_value'}
|
540
|
+
end
|
541
|
+
|
542
|
+
context 'with nested exceptions' do
|
543
|
+
let(:crashing_code) do
|
544
|
+
proc do
|
545
|
+
begin
|
546
|
+
begin
|
547
|
+
fail CauseException.new('the cause')
|
548
|
+
rescue
|
549
|
+
fail StandardError.new('the error')
|
550
|
+
end
|
551
|
+
rescue => e
|
552
|
+
e
|
553
|
+
end
|
554
|
+
end
|
555
|
+
end
|
556
|
+
|
557
|
+
let(:rescued_exception) { crashing_code.call }
|
558
|
+
let(:message) { 'message' }
|
559
|
+
let(:extra) { {} }
|
560
|
+
|
561
|
+
context 'using ruby >= 2.1' do
|
562
|
+
next unless Exception.instance_methods.include?(:cause)
|
563
|
+
|
564
|
+
it 'sends the two exceptions in the trace_chain attribute' do
|
565
|
+
body = notifier.send(:build_payload_body_exception, message, rescued_exception, extra)
|
566
|
+
|
567
|
+
body[:trace].should be_nil
|
568
|
+
body[:trace_chain].should be_kind_of(Array)
|
569
|
+
|
570
|
+
chain = body[:trace_chain]
|
571
|
+
chain[0][:exception][:class].should match(/StandardError/)
|
572
|
+
chain[0][:exception][:message].should match(/the error/)
|
573
|
+
|
574
|
+
chain[1][:exception][:class].should match(/CauseException/)
|
575
|
+
chain[1][:exception][:message].should match(/the cause/)
|
576
|
+
end
|
577
|
+
|
578
|
+
context 'using ruby <= 2.1' do
|
579
|
+
next if Exception.instance_methods.include?(:cause)
|
580
|
+
|
581
|
+
it 'sends only the last exception in the trace attribute' do
|
582
|
+
body = notifier.send(:build_payload_body_exception, message, rescued_exception, extra)
|
583
|
+
|
584
|
+
body[:trace].should be_kind_of(Hash)
|
585
|
+
body[:trace_chain].should be_nil
|
586
|
+
|
587
|
+
body[:trace][:exception][:class].should match(/StandardError/)
|
588
|
+
body[:trace][:exception][:message].should match(/the error/)
|
589
|
+
end
|
590
|
+
end
|
591
|
+
end
|
592
|
+
end
|
593
|
+
end
|
594
|
+
|
595
|
+
context 'build_payload_body_message' do
|
596
|
+
it 'should build a message' do
|
597
|
+
body = notifier.send(:build_payload_body_message, 'message', nil)
|
598
|
+
body[:message][:body].should == 'message'
|
599
|
+
body[:trace].should be_nil
|
600
|
+
end
|
601
|
+
|
602
|
+
it 'should build a message with extra data' do
|
603
|
+
extra_data = {:key => 'value', :hash => {:inner_key => 'inner_value'}}
|
604
|
+
body = notifier.send(:build_payload_body_message, 'message', extra_data)
|
605
|
+
body[:message][:body].should == 'message'
|
606
|
+
body[:message][:extra][:key].should == 'value'
|
607
|
+
body[:message][:extra][:hash].should == {:inner_key => 'inner_value'}
|
608
|
+
end
|
609
|
+
|
610
|
+
it 'should build an empty message with extra data' do
|
611
|
+
extra_data = {:key => 'value', :hash => {:inner_key => 'inner_value'}}
|
612
|
+
body = notifier.send(:build_payload_body_message, nil, extra_data)
|
613
|
+
body[:message][:body].should == 'Empty message'
|
614
|
+
body[:message][:extra][:key].should == 'value'
|
615
|
+
body[:message][:extra][:hash].should == {:inner_key => 'inner_value'}
|
616
|
+
end
|
617
|
+
end
|
618
|
+
|
619
|
+
context 'evaluate_payload' do
|
620
|
+
let(:notifier) do
|
621
|
+
notifier = Rollbar.notifier
|
622
|
+
|
623
|
+
notifier.configure do |config|
|
624
|
+
config.logger = logger_mock
|
625
|
+
end
|
626
|
+
|
627
|
+
notifier
|
628
|
+
end
|
629
|
+
|
630
|
+
let(:logger_mock) { double("Rails.logger").as_null_object }
|
631
|
+
|
632
|
+
before(:each) do
|
633
|
+
configure
|
634
|
+
notifier.configure do |config|
|
635
|
+
config.logger = logger_mock
|
636
|
+
end
|
637
|
+
end
|
638
|
+
|
639
|
+
it 'should evaluate callables and store the result' do
|
640
|
+
a = 'some string'
|
641
|
+
|
642
|
+
payload = {
|
643
|
+
:evaluate1 => lambda { 1 + 1 },
|
644
|
+
:evaluate2 => Proc.new { 2 + 2 },
|
645
|
+
:hash => {
|
646
|
+
:inner_evaluate1 => a.method(:to_s),
|
647
|
+
:inner_evaluate2 => lambda { {:key => 'value'} }
|
648
|
+
}
|
649
|
+
}
|
650
|
+
|
651
|
+
payload_copy = payload.clone
|
652
|
+
notifier.send(:evaluate_payload, payload_copy)
|
653
|
+
|
654
|
+
payload_copy[:evaluate1].should == 2
|
655
|
+
payload_copy[:evaluate2].should == 4
|
656
|
+
payload_copy[:hash][:inner_evaluate1].should == 'some string'
|
657
|
+
payload_copy[:hash][:inner_evaluate2][:key].should == 'value'
|
658
|
+
end
|
659
|
+
|
660
|
+
it 'should not crash when the callable raises an exception' do
|
661
|
+
logger_mock.should_receive(:error).with("[Rollbar] Error while evaluating callable in payload for key evaluate1")
|
662
|
+
|
663
|
+
payload = {
|
664
|
+
:evaluate1 => lambda { a = b },
|
665
|
+
:evaluate2 => Proc.new { 2 + 2 },
|
666
|
+
:key => 'value'
|
667
|
+
}
|
668
|
+
|
669
|
+
payload_copy = payload.clone
|
670
|
+
notifier.send(:evaluate_payload, payload_copy)
|
671
|
+
|
672
|
+
payload_copy[:evaluate1].should be_nil
|
673
|
+
payload_copy[:evaluate2].should == 4
|
674
|
+
payload_copy[:key].should == 'value'
|
22
675
|
end
|
676
|
+
end
|
677
|
+
|
678
|
+
context 'enforce_valid_utf8' do
|
679
|
+
it 'should replace invalid utf8 values' do
|
680
|
+
payload = {
|
681
|
+
:bad_value => "bad value 1\255",
|
682
|
+
:bad_value_2 => "bad\255 value 2",
|
683
|
+
"bad\255 key" => "good value",
|
684
|
+
:hash => {
|
685
|
+
:inner_bad_value => "\255\255bad value 3",
|
686
|
+
"inner \255bad key" => 'inner good value',
|
687
|
+
"bad array key\255" => [
|
688
|
+
'good array value 1',
|
689
|
+
"bad\255 array value 1\255",
|
690
|
+
{
|
691
|
+
:inner_inner_bad => "bad inner \255inner value"
|
692
|
+
}
|
693
|
+
]
|
694
|
+
}
|
695
|
+
}
|
23
696
|
|
697
|
+
payload_copy = payload.clone
|
698
|
+
notifier.send(:enforce_valid_utf8, payload_copy)
|
699
|
+
|
700
|
+
payload_copy[:bad_value].should == "bad value 1"
|
701
|
+
payload_copy[:bad_value_2].should == "bad value 2"
|
702
|
+
payload_copy["bad key"].should == "good value"
|
703
|
+
payload_copy.keys.should_not include("bad\456 key")
|
704
|
+
payload_copy[:hash][:inner_bad_value].should == "bad value 3"
|
705
|
+
payload_copy[:hash]["inner bad key"].should == 'inner good value'
|
706
|
+
payload_copy[:hash]["bad array key"].should == [
|
707
|
+
'good array value 1',
|
708
|
+
'bad array value 1',
|
709
|
+
{
|
710
|
+
:inner_inner_bad => 'bad inner inner value'
|
711
|
+
}
|
712
|
+
]
|
713
|
+
end
|
714
|
+
end
|
715
|
+
|
716
|
+
context 'truncate_payload' do
|
717
|
+
it 'should truncate all nested strings in the payload' do
|
718
|
+
payload = {
|
719
|
+
:truncated => '1234567',
|
720
|
+
:not_truncated => '123456',
|
721
|
+
:hash => {
|
722
|
+
:inner_truncated => '123456789',
|
723
|
+
:inner_not_truncated => '567',
|
724
|
+
:array => ['12345678', '12', {:inner_inner => '123456789'}]
|
725
|
+
}
|
726
|
+
}
|
727
|
+
|
728
|
+
payload_copy = payload.clone
|
729
|
+
notifier.send(:truncate_payload, payload_copy, 6)
|
730
|
+
|
731
|
+
payload_copy[:truncated].should == '123...'
|
732
|
+
payload_copy[:not_truncated].should == '123456'
|
733
|
+
payload_copy[:hash][:inner_truncated].should == '123...'
|
734
|
+
payload_copy[:hash][:inner_not_truncated].should == '567'
|
735
|
+
payload_copy[:hash][:array].should == ['123...', '12', {:inner_inner => '123...'}]
|
736
|
+
end
|
737
|
+
|
738
|
+
it 'should truncate utf8 strings properly' do
|
739
|
+
payload = {
|
740
|
+
:truncated => 'Ŝǻмρļẻ śţяịņģ',
|
741
|
+
:not_truncated => '123456',
|
742
|
+
}
|
743
|
+
|
744
|
+
payload_copy = payload.clone
|
745
|
+
notifier.send(:truncate_payload, payload_copy, 6)
|
746
|
+
|
747
|
+
payload_copy[:truncated].should == "Ŝǻм..."
|
748
|
+
payload_copy[:not_truncated].should == '123456'
|
749
|
+
end
|
750
|
+
end
|
751
|
+
end
|
752
|
+
|
753
|
+
context 'reporting' do
|
754
|
+
let(:exception) do
|
24
755
|
begin
|
25
756
|
foo = bar
|
26
757
|
rescue => e
|
27
|
-
|
758
|
+
e
|
28
759
|
end
|
29
760
|
end
|
30
761
|
|
31
762
|
let(:logger_mock) { double("Rails.logger").as_null_object }
|
763
|
+
let(:user) { User.create(:email => 'email@example.com', :encrypted_password => '', :created_at => Time.now, :updated_at => Time.now) }
|
764
|
+
|
765
|
+
before(:each) do
|
766
|
+
configure
|
767
|
+
Rollbar.configure do |config|
|
768
|
+
config.logger = logger_mock
|
769
|
+
end
|
770
|
+
end
|
771
|
+
|
772
|
+
after(:each) do
|
773
|
+
Rollbar.unconfigure
|
774
|
+
configure
|
775
|
+
end
|
32
776
|
|
33
777
|
it 'should report exceptions without person or request data' do
|
34
778
|
logger_mock.should_receive(:info).with('[Rollbar] Success')
|
35
|
-
Rollbar.
|
779
|
+
Rollbar.error(exception)
|
36
780
|
end
|
37
781
|
|
38
782
|
it 'should not report anything when disabled' do
|
39
783
|
logger_mock.should_not_receive(:info).with('[Rollbar] Success')
|
784
|
+
|
40
785
|
Rollbar.configure do |config|
|
41
786
|
config.enabled = false
|
42
787
|
end
|
43
788
|
|
44
|
-
Rollbar.
|
789
|
+
Rollbar.error(exception).should == 'disabled'
|
790
|
+
end
|
45
791
|
|
46
|
-
|
47
|
-
|
48
|
-
|
792
|
+
it 'should report exceptions without person or request data' do
|
793
|
+
logger_mock.should_receive(:info).with('[Rollbar] Success')
|
794
|
+
Rollbar.error(exception)
|
49
795
|
end
|
50
796
|
|
51
797
|
it 'should be enabled when freshly configured' do
|
@@ -56,65 +802,25 @@ describe Rollbar do
|
|
56
802
|
Rollbar.unconfigure
|
57
803
|
|
58
804
|
Rollbar.configuration.enabled.should be_nil
|
59
|
-
Rollbar.
|
805
|
+
Rollbar.error(exception).should == 'disabled'
|
60
806
|
end
|
61
807
|
|
62
|
-
it 'should stay disabled if configure is called again' do
|
63
|
-
Rollbar.unconfigure
|
64
|
-
|
65
|
-
# configure once, setting enabled to false.
|
66
|
-
Rollbar.configure do |config|
|
67
|
-
config.enabled = false
|
68
|
-
end
|
69
|
-
|
70
|
-
# now configure again (perhaps to change some other values)
|
71
|
-
Rollbar.configure do |config| end
|
72
|
-
|
73
|
-
Rollbar.configuration.enabled.should == false
|
74
|
-
Rollbar.report_exception(@exception).should == 'disabled'
|
75
|
-
end
|
76
|
-
|
77
|
-
it 'should report exceptions with request and person data' do
|
78
|
-
logger_mock.should_receive(:info).with('[Rollbar] Success')
|
79
|
-
request_data = {
|
80
|
-
:params => { :foo => "bar" },
|
81
|
-
:url => 'http://localhost/',
|
82
|
-
:user_ip => '127.0.0.1',
|
83
|
-
:headers => {},
|
84
|
-
:GET => { "baz" => "boz" },
|
85
|
-
:session => { :user_id => 123 },
|
86
|
-
:method => "GET",
|
87
|
-
}
|
88
|
-
person_data = {
|
89
|
-
:id => 1,
|
90
|
-
:username => "test",
|
91
|
-
:email => "test@example.com"
|
92
|
-
}
|
93
|
-
Rollbar.report_exception(@exception, request_data, person_data)
|
94
|
-
end
|
808
|
+
it 'should stay disabled if configure is called again' do
|
809
|
+
Rollbar.unconfigure
|
95
810
|
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
:env => { :"rack.errors" => IO.new(2, File::WRONLY) },
|
107
|
-
}
|
108
|
-
person_data = {
|
109
|
-
:id => 1,
|
110
|
-
:username => "test",
|
111
|
-
:email => "test@example.com"
|
112
|
-
}
|
113
|
-
Rollbar.report_exception(@exception, request_data, person_data)
|
811
|
+
# configure once, setting enabled to false.
|
812
|
+
Rollbar.configure do |config|
|
813
|
+
config.enabled = false
|
814
|
+
end
|
815
|
+
|
816
|
+
# now configure again (perhaps to change some other values)
|
817
|
+
Rollbar.configure do |config| end
|
818
|
+
|
819
|
+
Rollbar.configuration.enabled.should == false
|
820
|
+
Rollbar.error(exception).should == 'disabled'
|
114
821
|
end
|
115
822
|
|
116
823
|
it 'should ignore ignored exception classes' do
|
117
|
-
saved_filters = Rollbar.configuration.exception_level_filters
|
118
824
|
Rollbar.configure do |config|
|
119
825
|
config.exception_level_filters = { 'NameError' => 'ignore' }
|
120
826
|
end
|
@@ -123,15 +829,24 @@ describe Rollbar do
|
|
123
829
|
logger_mock.should_not_receive(:warn)
|
124
830
|
logger_mock.should_not_receive(:error)
|
125
831
|
|
126
|
-
Rollbar.
|
832
|
+
Rollbar.error(exception)
|
833
|
+
end
|
127
834
|
|
128
|
-
|
129
|
-
|
130
|
-
|
835
|
+
it "should work with an IO object as rack.errors" do
|
836
|
+
logger_mock.should_receive(:info).with('[Rollbar] Success')
|
837
|
+
|
838
|
+
Rollbar.error(exception, :env => { :"rack.errors" => IO.new(2, File::WRONLY) })
|
131
839
|
end
|
132
840
|
|
133
841
|
it 'should ignore ignored persons' do
|
842
|
+
person_data = {
|
843
|
+
:id => 1,
|
844
|
+
:username => "test",
|
845
|
+
:email => "test@example.com"
|
846
|
+
}
|
847
|
+
|
134
848
|
Rollbar.configure do |config|
|
849
|
+
config.payload_options = {:person => person_data}
|
135
850
|
config.ignored_person_ids += [1]
|
136
851
|
end
|
137
852
|
|
@@ -139,27 +854,23 @@ describe Rollbar do
|
|
139
854
|
logger_mock.should_not_receive(:warn)
|
140
855
|
logger_mock.should_not_receive(:error)
|
141
856
|
|
857
|
+
Rollbar.error(exception)
|
858
|
+
end
|
859
|
+
|
860
|
+
it 'should not ignore non-ignored persons' do
|
142
861
|
person_data = {
|
143
862
|
:id => 1,
|
144
863
|
:username => "test",
|
145
864
|
:email => "test@example.com"
|
146
865
|
}
|
147
|
-
Rollbar.report_exception(@exception, {}, person_data)
|
148
|
-
end
|
149
|
-
|
150
|
-
it 'should not ignore non-ignored persons' do
|
151
866
|
Rollbar.configure do |config|
|
867
|
+
config.payload_options = { :person => person_data }
|
152
868
|
config.ignored_person_ids += [1]
|
153
869
|
end
|
154
870
|
|
155
871
|
Rollbar.last_report = nil
|
156
872
|
|
157
|
-
|
158
|
-
:id => 1,
|
159
|
-
:username => "test",
|
160
|
-
:email => "test@example.com"
|
161
|
-
}
|
162
|
-
Rollbar.report_exception(@exception, {}, person_data)
|
873
|
+
Rollbar.error(exception)
|
163
874
|
Rollbar.last_report.should be_nil
|
164
875
|
|
165
876
|
person_data = {
|
@@ -167,7 +878,15 @@ describe Rollbar do
|
|
167
878
|
:username => "test2",
|
168
879
|
:email => "test2@example.com"
|
169
880
|
}
|
170
|
-
|
881
|
+
|
882
|
+
new_options = {
|
883
|
+
:person => person_data
|
884
|
+
}
|
885
|
+
|
886
|
+
Rollbar.scoped(new_options) do
|
887
|
+
Rollbar.error(exception)
|
888
|
+
end
|
889
|
+
|
171
890
|
Rollbar.last_report.should_not be_nil
|
172
891
|
end
|
173
892
|
|
@@ -178,20 +897,16 @@ describe Rollbar do
|
|
178
897
|
config.exception_level_filters = { 'NameError' => callable_mock }
|
179
898
|
end
|
180
899
|
|
181
|
-
callable_mock.should_receive(:call).with(
|
900
|
+
callable_mock.should_receive(:call).with(exception).at_least(:once).and_return("info")
|
182
901
|
logger_mock.should_receive(:info)
|
183
902
|
logger_mock.should_not_receive(:warn)
|
184
903
|
logger_mock.should_not_receive(:error)
|
185
904
|
|
186
|
-
Rollbar.
|
187
|
-
|
188
|
-
Rollbar.configure do |config|
|
189
|
-
config.exception_level_filters = saved_filters
|
190
|
-
end
|
905
|
+
Rollbar.error(exception)
|
191
906
|
end
|
192
907
|
|
193
908
|
it 'should not report exceptions when silenced' do
|
194
|
-
Rollbar.
|
909
|
+
expect_any_instance_of(Rollbar::Notifier).to_not receive(:schedule_payload)
|
195
910
|
|
196
911
|
begin
|
197
912
|
test_var = 1
|
@@ -200,7 +915,7 @@ describe Rollbar do
|
|
200
915
|
raise
|
201
916
|
end
|
202
917
|
rescue => e
|
203
|
-
Rollbar.
|
918
|
+
Rollbar.error(e)
|
204
919
|
end
|
205
920
|
|
206
921
|
test_var.should == 2
|
@@ -208,10 +923,13 @@ describe Rollbar do
|
|
208
923
|
|
209
924
|
it 'should report exception objects with no backtrace' do
|
210
925
|
payload = nil
|
211
|
-
|
926
|
+
|
927
|
+
notifier.stub(:schedule_payload) do |*args|
|
212
928
|
payload = args[0]
|
213
929
|
end
|
214
|
-
|
930
|
+
|
931
|
+
Rollbar.error(StandardError.new("oops"))
|
932
|
+
|
215
933
|
payload["data"][:body][:trace][:frames].should == []
|
216
934
|
payload["data"][:body][:trace][:exception][:class].should == "StandardError"
|
217
935
|
payload["data"][:body][:trace][:exception][:message].should == "oops"
|
@@ -219,15 +937,15 @@ describe Rollbar do
|
|
219
937
|
|
220
938
|
it 'should return the exception data with a uuid, on platforms with SecureRandom' do
|
221
939
|
if defined?(SecureRandom) and SecureRandom.respond_to?(:uuid)
|
222
|
-
Rollbar.
|
223
|
-
exception_data = Rollbar.report_exception(StandardError.new("oops"))
|
940
|
+
exception_data = Rollbar.error(StandardError.new("oops"))
|
224
941
|
exception_data[:uuid].should_not be_nil
|
225
942
|
end
|
226
943
|
end
|
227
944
|
|
228
945
|
it 'should report exception objects with nonstandard backtraces' do
|
229
946
|
payload = nil
|
230
|
-
|
947
|
+
|
948
|
+
notifier.stub(:schedule_payload) do |*args|
|
231
949
|
payload = args[0]
|
232
950
|
end
|
233
951
|
|
@@ -239,27 +957,29 @@ describe Rollbar do
|
|
239
957
|
|
240
958
|
exception = CustomException.new("oops")
|
241
959
|
|
242
|
-
|
960
|
+
notifier.error(exception)
|
243
961
|
|
244
962
|
payload["data"][:body][:trace][:frames][0][:method].should == "custom backtrace line"
|
245
963
|
end
|
246
964
|
|
247
965
|
it 'should report exceptions with a custom level' do
|
248
966
|
payload = nil
|
249
|
-
|
967
|
+
|
968
|
+
notifier.stub(:schedule_payload) do |*args|
|
250
969
|
payload = args[0]
|
251
970
|
end
|
252
971
|
|
253
|
-
Rollbar.
|
972
|
+
Rollbar.error(exception)
|
254
973
|
|
255
|
-
payload[
|
974
|
+
payload['data'][:level].should == 'error'
|
256
975
|
|
257
|
-
Rollbar.
|
976
|
+
Rollbar.log('debug', exception)
|
258
977
|
|
259
|
-
payload[
|
978
|
+
payload['data'][:level].should == 'debug'
|
260
979
|
end
|
261
980
|
end
|
262
981
|
|
982
|
+
# Backwards
|
263
983
|
context 'report_message' do
|
264
984
|
before(:each) do
|
265
985
|
configure
|
@@ -296,6 +1016,8 @@ describe Rollbar do
|
|
296
1016
|
:hash => { :a => 123, :b => "xyz" })
|
297
1017
|
end
|
298
1018
|
|
1019
|
+
# END Backwards
|
1020
|
+
|
299
1021
|
it 'should not crash with circular extra_data' do
|
300
1022
|
a = { :foo => "bar" }
|
301
1023
|
b = { :a => a }
|
@@ -304,7 +1026,7 @@ describe Rollbar do
|
|
304
1026
|
|
305
1027
|
logger_mock.should_receive(:error).with(/\[Rollbar\] Reporting internal error encountered while sending data to Rollbar./)
|
306
1028
|
|
307
|
-
Rollbar.
|
1029
|
+
Rollbar.error("Test message with circular extra data", a)
|
308
1030
|
end
|
309
1031
|
|
310
1032
|
it 'should be able to report form validation errors when they are present' do
|
@@ -319,36 +1041,13 @@ describe Rollbar do
|
|
319
1041
|
user.report_validation_errors_to_rollbar
|
320
1042
|
end
|
321
1043
|
|
322
|
-
|
323
|
-
Rollbar.configure do |config|
|
324
|
-
config.logger = ::Rails.logger
|
325
|
-
end
|
326
|
-
end
|
327
|
-
end
|
328
|
-
|
329
|
-
context 'report_message_with_request' do
|
330
|
-
before(:each) do
|
331
|
-
configure
|
332
|
-
Rollbar.configure do |config|
|
333
|
-
config.logger = logger_mock
|
334
|
-
end
|
335
|
-
end
|
336
|
-
|
337
|
-
let(:logger_mock) { double("Rails.logger").as_null_object }
|
338
|
-
let(:user) { User.create(:email => 'email@example.com', :encrypted_password => '', :created_at => Time.now, :updated_at => Time.now) }
|
339
|
-
|
340
|
-
it 'should report simple messages' do
|
341
|
-
logger_mock.should_receive(:info).with('[Rollbar] Scheduling payload')
|
1044
|
+
it 'should report messages with extra data' do
|
342
1045
|
logger_mock.should_receive(:info).with('[Rollbar] Success')
|
343
|
-
Rollbar.
|
344
|
-
|
345
|
-
Rollbar.last_report[:request].should be_nil
|
346
|
-
Rollbar.last_report[:person].should be_nil
|
1046
|
+
Rollbar.info("Test message with extra data", :foo => "bar",
|
1047
|
+
:hash => { :a => 123, :b => "xyz" })
|
347
1048
|
end
|
348
1049
|
|
349
1050
|
it 'should report messages with request, person data and extra data' do
|
350
|
-
Rollbar.last_report = nil
|
351
|
-
|
352
1051
|
logger_mock.should_receive(:info).with('[Rollbar] Scheduling payload')
|
353
1052
|
logger_mock.should_receive(:info).with('[Rollbar] Success')
|
354
1053
|
|
@@ -365,11 +1064,18 @@ describe Rollbar do
|
|
365
1064
|
:extra_foo => 'extra_bar'
|
366
1065
|
}
|
367
1066
|
|
368
|
-
Rollbar.
|
1067
|
+
Rollbar.configure do |config|
|
1068
|
+
config.payload_options = {
|
1069
|
+
:request => request_data,
|
1070
|
+
:person => person_data
|
1071
|
+
}
|
1072
|
+
end
|
1073
|
+
|
1074
|
+
Rollbar.info("Test message", extra_data)
|
369
1075
|
|
370
1076
|
Rollbar.last_report[:request].should == request_data
|
371
1077
|
Rollbar.last_report[:person].should == person_data
|
372
|
-
Rollbar.last_report[:body][:message][:extra_foo].should == 'extra_bar'
|
1078
|
+
Rollbar.last_report[:body][:message][:extra][:extra_foo].should == 'extra_bar'
|
373
1079
|
end
|
374
1080
|
end
|
375
1081
|
|
@@ -380,11 +1086,18 @@ describe Rollbar do
|
|
380
1086
|
config.logger = logger_mock
|
381
1087
|
config.filepath = 'test.rollbar'
|
382
1088
|
end
|
1089
|
+
end
|
1090
|
+
|
1091
|
+
after(:each) do
|
1092
|
+
Rollbar.unconfigure
|
1093
|
+
configure
|
1094
|
+
end
|
383
1095
|
|
1096
|
+
let(:exception) do
|
384
1097
|
begin
|
385
1098
|
foo = bar
|
386
1099
|
rescue => e
|
387
|
-
|
1100
|
+
e
|
388
1101
|
end
|
389
1102
|
end
|
390
1103
|
|
@@ -394,7 +1107,7 @@ describe Rollbar do
|
|
394
1107
|
logger_mock.should_not_receive(:info).with('[Rollbar] Writing payload to file')
|
395
1108
|
logger_mock.should_receive(:info).with('[Rollbar] Sending payload').once
|
396
1109
|
logger_mock.should_receive(:info).with('[Rollbar] Success').once
|
397
|
-
Rollbar.
|
1110
|
+
Rollbar.error(exception)
|
398
1111
|
end
|
399
1112
|
|
400
1113
|
it 'should save the payload to a file if set' do
|
@@ -409,7 +1122,7 @@ describe Rollbar do
|
|
409
1122
|
filepath = config.filepath
|
410
1123
|
end
|
411
1124
|
|
412
|
-
Rollbar.
|
1125
|
+
Rollbar.error(exception)
|
413
1126
|
|
414
1127
|
File.exist?(filepath).should == true
|
415
1128
|
File.read(filepath).should include test_access_token
|
@@ -427,11 +1140,18 @@ describe Rollbar do
|
|
427
1140
|
Rollbar.configure do |config|
|
428
1141
|
config.logger = logger_mock
|
429
1142
|
end
|
1143
|
+
end
|
1144
|
+
|
1145
|
+
after(:each) do
|
1146
|
+
Rollbar.unconfigure
|
1147
|
+
configure
|
1148
|
+
end
|
430
1149
|
|
1150
|
+
let(:exception) do
|
431
1151
|
begin
|
432
1152
|
foo = bar
|
433
1153
|
rescue => e
|
434
|
-
|
1154
|
+
e
|
435
1155
|
end
|
436
1156
|
end
|
437
1157
|
|
@@ -447,7 +1167,7 @@ describe Rollbar do
|
|
447
1167
|
GirlFriday::WorkQueue.immediate!
|
448
1168
|
end
|
449
1169
|
|
450
|
-
Rollbar.
|
1170
|
+
Rollbar.error(exception)
|
451
1171
|
|
452
1172
|
Rollbar.configure do |config|
|
453
1173
|
config.use_async = false
|
@@ -468,12 +1188,7 @@ describe Rollbar do
|
|
468
1188
|
}
|
469
1189
|
end
|
470
1190
|
|
471
|
-
Rollbar.
|
472
|
-
|
473
|
-
Rollbar.configure do |config|
|
474
|
-
config.use_async = false
|
475
|
-
config.async_handler = Rollbar.default_async_handler
|
476
|
-
end
|
1191
|
+
Rollbar.error(exception)
|
477
1192
|
end
|
478
1193
|
|
479
1194
|
# We should be able to send String payloads, generated
|
@@ -497,7 +1212,7 @@ describe Rollbar do
|
|
497
1212
|
it 'sends a payload generated as String, not as a Hash' do
|
498
1213
|
logger_mock.should_receive(:info).with('[Rollbar] Success')
|
499
1214
|
|
500
|
-
Rollbar.report_exception(
|
1215
|
+
Rollbar.report_exception(exception)
|
501
1216
|
end
|
502
1217
|
|
503
1218
|
context 'with async failover handlers' do
|
@@ -536,7 +1251,7 @@ describe Rollbar do
|
|
536
1251
|
it 'logs the error but doesnt try to report an internal error' do
|
537
1252
|
expect(logger_mock).to receive(:error).with(log_message)
|
538
1253
|
|
539
|
-
Rollbar.
|
1254
|
+
Rollbar.error(exception)
|
540
1255
|
end
|
541
1256
|
end
|
542
1257
|
|
@@ -548,7 +1263,7 @@ describe Rollbar do
|
|
548
1263
|
expect(Rollbar).not_to receive(:report_internal_error)
|
549
1264
|
expect(handler).to receive(:call)
|
550
1265
|
|
551
|
-
Rollbar.
|
1266
|
+
Rollbar.error(exception)
|
552
1267
|
end
|
553
1268
|
end
|
554
1269
|
|
@@ -560,7 +1275,7 @@ describe Rollbar do
|
|
560
1275
|
it 'calls the second handler and doesnt report internal error' do
|
561
1276
|
expect(handler2).to receive(:call)
|
562
1277
|
|
563
|
-
Rollbar.
|
1278
|
+
Rollbar.error(exception)
|
564
1279
|
end
|
565
1280
|
end
|
566
1281
|
|
@@ -572,7 +1287,7 @@ describe Rollbar do
|
|
572
1287
|
it 'reports internal error' do
|
573
1288
|
expect(logger_mock).to receive(:error)
|
574
1289
|
|
575
|
-
Rollbar.
|
1290
|
+
Rollbar.error(exception)
|
576
1291
|
end
|
577
1292
|
end
|
578
1293
|
end
|
@@ -589,12 +1304,7 @@ describe Rollbar do
|
|
589
1304
|
config.use_sucker_punch
|
590
1305
|
end
|
591
1306
|
|
592
|
-
Rollbar.
|
593
|
-
|
594
|
-
Rollbar.configure do |config|
|
595
|
-
config.use_async = false
|
596
|
-
config.async_handler = Rollbar.default_async_handler
|
597
|
-
end
|
1307
|
+
Rollbar.error(exception)
|
598
1308
|
end
|
599
1309
|
end
|
600
1310
|
|
@@ -614,161 +1324,7 @@ describe Rollbar do
|
|
614
1324
|
config.async_handler = handler
|
615
1325
|
end
|
616
1326
|
|
617
|
-
Rollbar.
|
618
|
-
|
619
|
-
Rollbar.configure do |config|
|
620
|
-
config.use_async = false
|
621
|
-
config.async_handler = Rollbar.default_async_handler
|
622
|
-
end
|
623
|
-
end
|
624
|
-
end
|
625
|
-
end
|
626
|
-
|
627
|
-
context 'message_data' do
|
628
|
-
before(:each) do
|
629
|
-
configure
|
630
|
-
@message_body = "This is a test"
|
631
|
-
@level = 'debug'
|
632
|
-
end
|
633
|
-
|
634
|
-
it 'should build a message' do
|
635
|
-
data = Rollbar.send(:message_data, @message_body, @level, {})
|
636
|
-
data[:body][:message][:body].should == @message_body
|
637
|
-
data[:level].should == @level
|
638
|
-
data[:custom].should be_nil
|
639
|
-
end
|
640
|
-
|
641
|
-
it 'should accept extra_data' do
|
642
|
-
user_id = 123
|
643
|
-
name = "Tester"
|
644
|
-
|
645
|
-
data = Rollbar.send(:message_data, @message_body, 'info',
|
646
|
-
:user_id => user_id, :name => name)
|
647
|
-
|
648
|
-
data[:level].should == 'info'
|
649
|
-
message = data[:body][:message]
|
650
|
-
message[:body].should == @message_body
|
651
|
-
message[:user_id].should == user_id
|
652
|
-
message[:name].should == name
|
653
|
-
end
|
654
|
-
|
655
|
-
it 'should build a message with custom data when configured' do
|
656
|
-
Rollbar.configure do |config|
|
657
|
-
config.custom_data_method = lambda { {:foo => "bar", :hello => [1, 2, 3]} }
|
658
|
-
end
|
659
|
-
|
660
|
-
data = Rollbar.send(:message_data, @message_body, @level, {})
|
661
|
-
|
662
|
-
data[:level].should == @level
|
663
|
-
data[:body][:message][:body].should == @message_body
|
664
|
-
data[:custom].should_not be_nil
|
665
|
-
data[:custom][:foo].should == "bar"
|
666
|
-
data[:custom][:hello][2].should == 3
|
667
|
-
|
668
|
-
Rollbar.configure do |config|
|
669
|
-
config.custom_data_method = nil
|
670
|
-
end
|
671
|
-
end
|
672
|
-
end
|
673
|
-
|
674
|
-
describe '.exception_data' do
|
675
|
-
before(:each) do
|
676
|
-
configure
|
677
|
-
begin
|
678
|
-
foo = bar
|
679
|
-
rescue => e
|
680
|
-
@exception = e
|
681
|
-
end
|
682
|
-
end
|
683
|
-
|
684
|
-
it 'should accept force_level' do
|
685
|
-
level = 'critical'
|
686
|
-
data = Rollbar.send(:exception_data, @exception, level)
|
687
|
-
data[:level].should == level
|
688
|
-
end
|
689
|
-
|
690
|
-
it 'should build valid exception data' do
|
691
|
-
data = Rollbar.send(:exception_data, @exception)
|
692
|
-
|
693
|
-
data[:level].should_not be_nil
|
694
|
-
data[:custom].should be_nil
|
695
|
-
|
696
|
-
trace = data[:body][:trace]
|
697
|
-
|
698
|
-
frames = trace[:frames]
|
699
|
-
frames.should be_a_kind_of(Array)
|
700
|
-
frames.each do |frame|
|
701
|
-
frame[:filename].should be_a_kind_of(String)
|
702
|
-
frame[:lineno].should be_a_kind_of(Fixnum)
|
703
|
-
if frame[:method]
|
704
|
-
frame[:method].should be_a_kind_of(String)
|
705
|
-
end
|
706
|
-
end
|
707
|
-
|
708
|
-
# should be NameError, but can be NoMethodError sometimes on rubinius 1.8
|
709
|
-
# http://yehudakatz.com/2010/01/02/the-craziest-fing-bug-ive-ever-seen/
|
710
|
-
trace[:exception][:class].should match(/^(NameError|NoMethodError)$/)
|
711
|
-
trace[:exception][:message].should match(/^(undefined local variable or method `bar'|undefined method `bar' on an instance of)/)
|
712
|
-
end
|
713
|
-
|
714
|
-
it 'should include custom data when configured' do
|
715
|
-
Rollbar.configure do |config|
|
716
|
-
config.custom_data_method = lambda { {:foo => "baz", :hello => [4, 5, 6]} }
|
717
|
-
end
|
718
|
-
|
719
|
-
data = Rollbar.send(:exception_data, @exception)
|
720
|
-
data[:body][:trace].should_not be_nil
|
721
|
-
data[:custom][:foo].should == "baz"
|
722
|
-
data[:custom][:hello][2].should == 6
|
723
|
-
|
724
|
-
Rollbar.configure do |config|
|
725
|
-
config.custom_data_method = nil
|
726
|
-
end
|
727
|
-
end
|
728
|
-
|
729
|
-
context 'with nested exceptions' do
|
730
|
-
let(:crashing_code) do
|
731
|
-
proc do
|
732
|
-
begin
|
733
|
-
begin
|
734
|
-
fail CauseException.new('the cause')
|
735
|
-
rescue
|
736
|
-
fail StandardError.new('the error')
|
737
|
-
end
|
738
|
-
rescue => e
|
739
|
-
e
|
740
|
-
end
|
741
|
-
end
|
742
|
-
end
|
743
|
-
let(:rescued_exception) { crashing_code.call }
|
744
|
-
|
745
|
-
if Exception.instance_methods.include?(:cause)
|
746
|
-
it 'sends the two exceptions in the trace_chain attribute' do
|
747
|
-
data = Rollbar.send(:exception_data, rescued_exception)
|
748
|
-
body = data[:body]
|
749
|
-
|
750
|
-
body[:trace].should be_nil
|
751
|
-
body[:trace_chain].should be_kind_of(Array)
|
752
|
-
|
753
|
-
chain = body[:trace_chain]
|
754
|
-
chain[0][:exception][:class].should match(/StandardError/)
|
755
|
-
chain[0][:exception][:message].should match(/the error/)
|
756
|
-
|
757
|
-
chain[1][:exception][:class].should match(/CauseException/)
|
758
|
-
chain[1][:exception][:message].should match(/the cause/)
|
759
|
-
end
|
760
|
-
|
761
|
-
else
|
762
|
-
it 'sends only the last exception in the trace attribute' do
|
763
|
-
data = Rollbar.send(:exception_data, rescued_exception)
|
764
|
-
body = data[:body]
|
765
|
-
|
766
|
-
body[:trace].should be_kind_of(Hash)
|
767
|
-
body[:trace_chain].should be_nil
|
768
|
-
|
769
|
-
body[:trace][:exception][:class].should match(/StandardError/)
|
770
|
-
body[:trace][:exception][:message].should match(/the error/)
|
771
|
-
end
|
1327
|
+
Rollbar.error(exception)
|
772
1328
|
end
|
773
1329
|
end
|
774
1330
|
end
|
@@ -780,15 +1336,18 @@ describe Rollbar do
|
|
780
1336
|
|
781
1337
|
it 'should have use the Rails logger when configured to do so' do
|
782
1338
|
configure
|
783
|
-
Rollbar.send(:logger).
|
1339
|
+
expect(Rollbar.send(:logger)).to be_kind_of(Rollbar::LoggerProxy)
|
1340
|
+
expect(Rollbar.send(:logger).object).should == ::Rails.logger
|
784
1341
|
end
|
785
1342
|
|
786
1343
|
it 'should use the default_logger when no logger is set' do
|
787
1344
|
logger = Logger.new(STDERR)
|
1345
|
+
|
788
1346
|
Rollbar.configure do |config|
|
789
1347
|
config.default_logger = lambda { logger }
|
790
1348
|
end
|
791
|
-
|
1349
|
+
|
1350
|
+
Rollbar.send(:logger).object.should == logger
|
792
1351
|
end
|
793
1352
|
|
794
1353
|
it 'should have a default default_logger' do
|
@@ -800,72 +1359,11 @@ describe Rollbar do
|
|
800
1359
|
end
|
801
1360
|
end
|
802
1361
|
|
803
|
-
context 'build_payload' do
|
804
|
-
before(:each) do
|
805
|
-
configure
|
806
|
-
Rollbar.configure do |config|
|
807
|
-
config.logger = logger_mock
|
808
|
-
end
|
809
|
-
end
|
810
|
-
|
811
|
-
let(:logger_mock) { double("Rails.logger").as_null_object }
|
812
|
-
|
813
|
-
it 'should build valid json' do
|
814
|
-
data = { :foo => { :bar => 'baz'}}
|
815
|
-
payload = Rollbar.send(:build_payload, data)
|
816
|
-
payload["data"][:foo][:bar].should == "baz"
|
817
|
-
end
|
818
|
-
|
819
|
-
it 'should strip out invalid utf-8' do
|
820
|
-
payload = Rollbar.send(:build_payload, {
|
821
|
-
:good_key => "\255bad value",
|
822
|
-
"bad\255 key" => "good value",
|
823
|
-
"bad key 2\255" => "bad \255value",
|
824
|
-
:hash => {
|
825
|
-
"bad array \255key" => ["bad\255 array element", "good array element"]
|
826
|
-
}
|
827
|
-
})
|
828
|
-
|
829
|
-
payload["data"][:good_key].should == 'bad value'
|
830
|
-
payload["data"]["bad key"].should == 'good value'
|
831
|
-
payload["data"]["bad key 2"].should == 'bad value'
|
832
|
-
payload["data"][:hash].should == {
|
833
|
-
"bad array key" => ["bad array element", "good array element"]
|
834
|
-
}
|
835
|
-
end
|
836
|
-
|
837
|
-
it 'should truncate large strings if the payload is too big' do
|
838
|
-
data = {:foo => {:bar => "baz"}, :large => 'a' * (128 * 1024), :small => 'b' * 1024}
|
839
|
-
payload = Rollbar.send(:build_payload, data)
|
840
|
-
json = Rollbar.send(:dump_payload, payload)
|
841
|
-
|
842
|
-
hash = MultiJson.load(json)
|
843
|
-
hash["data"]["large"].should == '%s...' % ('a' * 1021)
|
844
|
-
hash["data"]["small"].should == 'b' * 1024
|
845
|
-
end
|
846
|
-
|
847
|
-
it 'should send a failsafe message if the payload cannot be reduced enough' do
|
848
|
-
logger_mock.should_receive(:error).with(/Sending failsafe response due to Could not send payload due to it being too large after truncating attempts/)
|
849
|
-
logger_mock.should_receive(:info).with('[Rollbar] Success')
|
850
|
-
|
851
|
-
orig_max = Rollbar::MAX_PAYLOAD_SIZE
|
852
|
-
Rollbar::MAX_PAYLOAD_SIZE = 1
|
853
|
-
orig_send_failsafe = Rollbar.method(:send_failsafe)
|
854
|
-
|
855
|
-
Rollbar.stub(:send_failsafe) do |message, exception|
|
856
|
-
Rollbar::MAX_PAYLOAD_SIZE = orig_max
|
857
|
-
orig_send_failsafe.call(message, exception)
|
858
|
-
end
|
859
|
-
|
860
|
-
Rollbar.report_exception(@exception)
|
861
|
-
end
|
862
|
-
end
|
863
|
-
|
864
1362
|
context 'enforce_valid_utf8' do
|
865
1363
|
it 'should replace invalid utf8 values' do
|
866
1364
|
bad_key = "inner \x92bad key"
|
867
1365
|
bad_key.force_encoding('ASCII-8BIT') if bad_key.respond_to?('force_encoding')
|
868
|
-
|
1366
|
+
|
869
1367
|
payload = {
|
870
1368
|
:bad_value => "bad value 1\255",
|
871
1369
|
:bad_value_2 => "bad\255 value 2",
|
@@ -884,7 +1382,7 @@ describe Rollbar do
|
|
884
1382
|
}
|
885
1383
|
|
886
1384
|
payload_copy = payload.clone
|
887
|
-
|
1385
|
+
notifier.send(:enforce_valid_utf8, payload_copy)
|
888
1386
|
|
889
1387
|
payload_copy[:bad_value].should == "bad value 1"
|
890
1388
|
payload_copy[:bad_value_2].should == "bad value 2"
|
@@ -915,7 +1413,7 @@ describe Rollbar do
|
|
915
1413
|
}
|
916
1414
|
|
917
1415
|
payload_copy = payload.clone
|
918
|
-
|
1416
|
+
notifier.send(:truncate_payload, payload_copy, 6)
|
919
1417
|
|
920
1418
|
payload_copy[:truncated].should == '123...'
|
921
1419
|
payload_copy[:not_truncated].should == '123456'
|
@@ -931,67 +1429,16 @@ describe Rollbar do
|
|
931
1429
|
}
|
932
1430
|
|
933
1431
|
payload_copy = payload.clone
|
934
|
-
|
1432
|
+
notifier.send(:truncate_payload, payload_copy, 6)
|
935
1433
|
|
936
1434
|
payload_copy[:truncated].should == "Ŝǻм..."
|
937
1435
|
payload_copy[:not_truncated].should == '123456'
|
938
1436
|
end
|
939
1437
|
end
|
940
1438
|
|
941
|
-
context 'base_data' do
|
942
|
-
before(:each) { configure }
|
943
|
-
|
944
|
-
it 'should have the correct notifier name' do
|
945
|
-
Rollbar.send(:base_data)[:notifier][:name].should == 'rollbar-gem'
|
946
|
-
end
|
947
|
-
|
948
|
-
it 'should have the correct notifier version' do
|
949
|
-
Rollbar.send(:base_data)[:notifier][:version].should == Rollbar::VERSION
|
950
|
-
end
|
951
|
-
|
952
|
-
it 'should have all the required keys' do
|
953
|
-
data = Rollbar.send(:base_data)
|
954
|
-
data[:timestamp].should_not be_nil
|
955
|
-
data[:environment].should_not be_nil
|
956
|
-
data[:level].should_not be_nil
|
957
|
-
data[:language].should == 'ruby'
|
958
|
-
data[:framework].should match(/^Rails/)
|
959
|
-
end
|
960
|
-
|
961
|
-
it 'should have default environment "unspecified"' do
|
962
|
-
data = Rollbar.send(:base_data)
|
963
|
-
data[:environment].should == 'unspecified'
|
964
|
-
end
|
965
|
-
|
966
|
-
it 'should have an overridden environment' do
|
967
|
-
Rollbar.configure do |config|
|
968
|
-
config.environment = 'overridden'
|
969
|
-
end
|
970
|
-
|
971
|
-
data = Rollbar.send(:base_data)
|
972
|
-
data[:environment].should == 'overridden'
|
973
|
-
end
|
974
|
-
|
975
|
-
it 'should not have custom data under default configuration' do
|
976
|
-
data = Rollbar.send(:base_data)
|
977
|
-
data[:custom].should be_nil
|
978
|
-
end
|
979
|
-
|
980
|
-
it 'should have custom data when custom_data_method is configured' do
|
981
|
-
Rollbar.configure do |config|
|
982
|
-
config.custom_data_method = lambda { {:a => 1, :b => [2, 3, 4]} }
|
983
|
-
end
|
984
|
-
|
985
|
-
data = Rollbar.send(:base_data)
|
986
|
-
data[:custom].should_not be_nil
|
987
|
-
data[:custom][:a].should == 1
|
988
|
-
data[:custom][:b][2].should == 4
|
989
|
-
end
|
990
|
-
end
|
991
|
-
|
992
1439
|
context 'server_data' do
|
993
1440
|
it 'should have the right hostname' do
|
994
|
-
|
1441
|
+
notifier.send(:server_data)[:host] == Socket.gethostname
|
995
1442
|
end
|
996
1443
|
|
997
1444
|
it 'should have root and branch set when configured' do
|
@@ -1001,7 +1448,7 @@ describe Rollbar do
|
|
1001
1448
|
config.branch = 'master'
|
1002
1449
|
end
|
1003
1450
|
|
1004
|
-
data =
|
1451
|
+
data = notifier.send(:server_data)
|
1005
1452
|
data[:root].should == '/path/to/root'
|
1006
1453
|
data[:branch].should == 'master'
|
1007
1454
|
end
|
@@ -1020,7 +1467,7 @@ describe Rollbar do
|
|
1020
1467
|
gem_paths.push(Gem::Specification.find_by_name(gem).gem_dir)
|
1021
1468
|
}
|
1022
1469
|
|
1023
|
-
data =
|
1470
|
+
data = notifier.send(:build_payload, 'info', 'test', nil, {})['data']
|
1024
1471
|
data[:project_package_paths].kind_of?(Array).should == true
|
1025
1472
|
data[:project_package_paths].length.should == gem_paths.length
|
1026
1473
|
|
@@ -1043,7 +1490,7 @@ describe Rollbar do
|
|
1043
1490
|
gem_paths.any?{|path| path.include? 'rollbar-gem'}.should == true
|
1044
1491
|
gem_paths.any?{|path| path.include? 'rspec-rails'}.should == true
|
1045
1492
|
|
1046
|
-
data =
|
1493
|
+
data = notifier.send(:build_payload, 'info', 'test', nil, {})['data']
|
1047
1494
|
data[:project_package_paths].kind_of?(Array).should == true
|
1048
1495
|
data[:project_package_paths].length.should == gem_paths.length
|
1049
1496
|
(data[:project_package_paths] - gem_paths).length.should == 0
|
@@ -1056,7 +1503,7 @@ describe Rollbar do
|
|
1056
1503
|
config.project_gems = gems
|
1057
1504
|
end
|
1058
1505
|
|
1059
|
-
data =
|
1506
|
+
data = notifier.send(:build_payload, 'info', 'test', nil, {})['data']
|
1060
1507
|
data[:project_package_paths].kind_of?(Array).should == true
|
1061
1508
|
data[:project_package_paths].length.should == 1
|
1062
1509
|
end
|
@@ -1067,7 +1514,7 @@ describe Rollbar do
|
|
1067
1514
|
begin
|
1068
1515
|
1 / 0
|
1069
1516
|
rescue => e
|
1070
|
-
|
1517
|
+
notifier.send(:report_internal_error, e)
|
1071
1518
|
end
|
1072
1519
|
end
|
1073
1520
|
end
|
@@ -1077,12 +1524,12 @@ describe Rollbar do
|
|
1077
1524
|
begin
|
1078
1525
|
1 / 0
|
1079
1526
|
rescue => e
|
1080
|
-
|
1527
|
+
notifier.send(:send_failsafe, "test failsafe", e)
|
1081
1528
|
end
|
1082
1529
|
end
|
1083
1530
|
|
1084
1531
|
it "should not crash when given all nils" do
|
1085
|
-
|
1532
|
+
notifier.send(:send_failsafe, nil, nil)
|
1086
1533
|
end
|
1087
1534
|
end
|
1088
1535
|
|
@@ -1104,6 +1551,69 @@ describe Rollbar do
|
|
1104
1551
|
end
|
1105
1552
|
end
|
1106
1553
|
|
1554
|
+
describe '.scoped' do
|
1555
|
+
let(:scope_options) do
|
1556
|
+
{ :foo => 'bar' }
|
1557
|
+
end
|
1558
|
+
|
1559
|
+
it 'changes payload options inside the block' do
|
1560
|
+
Rollbar.reset_notifier!
|
1561
|
+
configure
|
1562
|
+
|
1563
|
+
current_notifier_id = Rollbar.notifier.object_id
|
1564
|
+
|
1565
|
+
Rollbar.scoped(scope_options) do
|
1566
|
+
configuration = Rollbar.notifier.configuration
|
1567
|
+
|
1568
|
+
expect(Rollbar.notifier.object_id).not_to be_eql(current_notifier_id)
|
1569
|
+
expect(configuration.payload_options).to be_eql(scope_options)
|
1570
|
+
end
|
1571
|
+
|
1572
|
+
expect(Rollbar.notifier.object_id).to be_eql(current_notifier_id)
|
1573
|
+
end
|
1574
|
+
|
1575
|
+
context 'if the block fails' do
|
1576
|
+
let(:crashing_block) { proc { fail } }
|
1577
|
+
|
1578
|
+
it 'restores the old notifier' do
|
1579
|
+
notifier = Rollbar.notifier
|
1580
|
+
|
1581
|
+
expect { Rollbar.scoped(&crashing_block) }.to raise_error
|
1582
|
+
expect(notifier).to be_eql(Rollbar.notifier)
|
1583
|
+
end
|
1584
|
+
end
|
1585
|
+
|
1586
|
+
context 'if the block creates a new thread' do
|
1587
|
+
let(:block) do
|
1588
|
+
proc do
|
1589
|
+
Thread.new do
|
1590
|
+
scope = Rollbar.notifier.configuration.payload_options
|
1591
|
+
Thread.main[:inner_scope] = scope
|
1592
|
+
end.join
|
1593
|
+
end
|
1594
|
+
end
|
1595
|
+
|
1596
|
+
let(:scope) do
|
1597
|
+
{ :foo => 'bar' }
|
1598
|
+
end
|
1599
|
+
|
1600
|
+
it 'maintains the parent thread notifier scope' do
|
1601
|
+
Rollbar.scoped(scope, &block)
|
1602
|
+
|
1603
|
+
expect(Thread.main[:inner_scope]).to be_eql(scope)
|
1604
|
+
end
|
1605
|
+
end
|
1606
|
+
end
|
1607
|
+
|
1608
|
+
describe '.reset_notifier' do
|
1609
|
+
it 'resets the notifier' do
|
1610
|
+
notifier1_id = Rollbar.notifier.object_id
|
1611
|
+
|
1612
|
+
Rollbar.reset_notifier!
|
1613
|
+
expect(Rollbar.notifier.object_id).not_to be_eql(notifier1_id)
|
1614
|
+
end
|
1615
|
+
end
|
1616
|
+
|
1107
1617
|
# configure with some basic params
|
1108
1618
|
def configure
|
1109
1619
|
Rollbar.reconfigure do |config|
|