rollbar 2.10.0 → 2.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.travis.yml +7 -2
- data/CHANGELOG.md +20 -0
- data/README.md +73 -16
- data/docs/configuration.md +10 -0
- data/gemfiles/rails30.gemfile +2 -0
- data/gemfiles/rails31.gemfile +2 -0
- data/gemfiles/rails32.gemfile +2 -0
- data/gemfiles/rails40.gemfile +2 -0
- data/gemfiles/rails41.gemfile +2 -0
- data/gemfiles/rails42.gemfile +2 -0
- data/gemfiles/rails50.gemfile +2 -0
- data/gemfiles/ruby_1_8_and_1_9_2.gemfile +43 -0
- data/lib/rollbar.rb +139 -353
- data/lib/rollbar/configuration.rb +4 -0
- data/lib/rollbar/item.rb +225 -0
- data/lib/rollbar/item/backtrace.rb +97 -0
- data/lib/rollbar/js.rb +0 -28
- data/lib/rollbar/language_support.rb +10 -0
- data/lib/rollbar/{js/middleware.rb → middleware/js.rb} +3 -4
- data/lib/rollbar/plugin.rb +63 -0
- data/lib/rollbar/plugins.rb +41 -0
- data/lib/rollbar/{active_job.rb → plugins/active_job.rb} +0 -0
- data/lib/rollbar/plugins/basic_socket.rb +16 -0
- data/lib/rollbar/plugins/delayed_job.rb +12 -0
- data/lib/rollbar/plugins/delayed_job/job_data.rb +16 -0
- data/lib/rollbar/{delayed_job.rb → plugins/delayed_job/plugin.rb} +1 -17
- data/lib/rollbar/plugins/goalie.rb +46 -0
- data/lib/rollbar/plugins/rack.rb +16 -0
- data/lib/rollbar/plugins/rails.rb +77 -0
- data/lib/rollbar/{rails → plugins/rails}/controller_methods.rb +0 -0
- data/lib/rollbar/plugins/rails/railtie30.rb +17 -0
- data/lib/rollbar/plugins/rails/railtie32.rb +18 -0
- data/lib/rollbar/plugins/rails/railtie_mixin.rb +33 -0
- data/lib/rollbar/plugins/rake.rb +45 -0
- data/lib/rollbar/plugins/sidekiq.rb +35 -0
- data/lib/rollbar/{sidekiq.rb → plugins/sidekiq/plugin.rb} +0 -18
- data/lib/rollbar/plugins/thread.rb +13 -0
- data/lib/rollbar/plugins/validations.rb +33 -0
- data/lib/rollbar/request_data_extractor.rb +30 -18
- data/lib/rollbar/scrubbers/params.rb +4 -2
- data/lib/rollbar/scrubbers/url.rb +30 -28
- data/lib/rollbar/util.rb +10 -0
- data/lib/rollbar/version.rb +1 -1
- data/spec/controllers/home_controller_spec.rb +4 -3
- data/spec/dummyapp/app/models/post.rb +9 -0
- data/spec/dummyapp/app/models/user.rb +2 -0
- data/spec/dummyapp/config/initializers/rollbar.rb +1 -0
- data/spec/fixtures/plugins/dummy1.rb +5 -0
- data/spec/fixtures/plugins/dummy2.rb +5 -0
- data/spec/rollbar/item_spec.rb +635 -0
- data/spec/rollbar/logger_proxy_spec.rb +4 -0
- data/spec/rollbar/{js/middleware_spec.rb → middleware/js_spec.rb} +32 -3
- data/spec/rollbar/plugin_spec.rb +147 -0
- data/spec/rollbar/{active_job_spec.rb → plugins/active_job_spec.rb} +0 -1
- data/spec/rollbar/{delayed_job → plugins/delayed_job}/job_data.rb +0 -0
- data/spec/rollbar/{delayed_job_spec.rb → plugins/delayed_job_spec.rb} +3 -6
- data/spec/rollbar/{middleware/rack/builder_spec.rb → plugins/rack_spec.rb} +2 -1
- data/spec/rollbar/{js/frameworks/rails_spec.rb → plugins/rails_js_spec.rb} +1 -1
- data/spec/rollbar/{rake_spec.rb → plugins/rake_spec.rb} +2 -1
- data/spec/rollbar/{sidekiq_spec.rb → plugins/sidekiq_spec.rb} +2 -1
- data/spec/rollbar/plugins/validations_spec.rb +43 -0
- data/spec/rollbar/plugins_spec.rb +68 -0
- data/spec/rollbar/request_data_extractor_spec.rb +56 -10
- data/spec/rollbar/scrubbers/params_spec.rb +13 -10
- data/spec/rollbar/scrubbers/url_spec.rb +17 -12
- data/spec/rollbar/sidekig/clear_scope_spec.rb +2 -1
- data/spec/rollbar/util_spec.rb +61 -0
- data/spec/rollbar_bc_spec.rb +10 -10
- data/spec/rollbar_spec.rb +57 -706
- data/spec/spec_helper.rb +8 -0
- data/spec/support/notifier_helpers.rb +1 -0
- data/spec/support/rollbar_api.rb +57 -0
- metadata +57 -33
- data/lib/rollbar/active_record_extension.rb +0 -14
- data/lib/rollbar/core_ext/basic_socket.rb +0 -7
- data/lib/rollbar/core_ext/thread.rb +0 -9
- data/lib/rollbar/goalie.rb +0 -33
- data/lib/rollbar/js/frameworks.rb +0 -6
- data/lib/rollbar/js/frameworks/rails.rb +0 -49
- data/lib/rollbar/js/version.rb +0 -5
- data/lib/rollbar/rack.rb +0 -9
- data/lib/rollbar/railtie.rb +0 -46
- data/lib/rollbar/rake.rb +0 -40
@@ -15,8 +15,11 @@ describe Rollbar::Scrubbers::Params do
|
|
15
15
|
end
|
16
16
|
|
17
17
|
describe '#call' do
|
18
|
-
|
19
|
-
|
18
|
+
let(:options) do
|
19
|
+
{
|
20
|
+
:params => params,
|
21
|
+
:config => scrub_config
|
22
|
+
}
|
20
23
|
end
|
21
24
|
|
22
25
|
context 'with scrub fields configured' do
|
@@ -43,7 +46,7 @@ describe Rollbar::Scrubbers::Params do
|
|
43
46
|
end
|
44
47
|
|
45
48
|
it 'scrubs the required parameters' do
|
46
|
-
expect(subject.call(
|
49
|
+
expect(subject.call(options)).to be_eql_hash_with_regexes(result)
|
47
50
|
end
|
48
51
|
end
|
49
52
|
|
@@ -70,7 +73,7 @@ describe Rollbar::Scrubbers::Params do
|
|
70
73
|
end
|
71
74
|
|
72
75
|
it 'scrubs the required parameters' do
|
73
|
-
expect(subject.call(
|
76
|
+
expect(subject.call(options)).to be_eql_hash_with_regexes(result)
|
74
77
|
end
|
75
78
|
end
|
76
79
|
|
@@ -97,7 +100,7 @@ describe Rollbar::Scrubbers::Params do
|
|
97
100
|
end
|
98
101
|
|
99
102
|
it 'scrubs the required parameters' do
|
100
|
-
expect(subject.call(
|
103
|
+
expect(subject.call(options)).to be_eql_hash_with_regexes(result)
|
101
104
|
end
|
102
105
|
end
|
103
106
|
|
@@ -129,7 +132,7 @@ describe Rollbar::Scrubbers::Params do
|
|
129
132
|
after { tempfile.close }
|
130
133
|
|
131
134
|
it 'scrubs the required parameters' do
|
132
|
-
expect(subject.call(
|
135
|
+
expect(subject.call(options)).to be_eql_hash_with_regexes(result)
|
133
136
|
end
|
134
137
|
end
|
135
138
|
|
@@ -169,7 +172,7 @@ describe Rollbar::Scrubbers::Params do
|
|
169
172
|
end
|
170
173
|
|
171
174
|
it 'scrubs the required parameters' do
|
172
|
-
expect(subject.call(
|
175
|
+
expect(subject.call(options)).to be_eql_hash_with_regexes(result)
|
173
176
|
end
|
174
177
|
|
175
178
|
context 'if getting the attachment values fails' do
|
@@ -204,7 +207,7 @@ describe Rollbar::Scrubbers::Params do
|
|
204
207
|
end
|
205
208
|
|
206
209
|
it 'scrubs the required parameters' do
|
207
|
-
expect(subject.call(
|
210
|
+
expect(subject.call(options)).to be_eql_hash_with_regexes(result)
|
208
211
|
end
|
209
212
|
end
|
210
213
|
end
|
@@ -218,7 +221,7 @@ describe Rollbar::Scrubbers::Params do
|
|
218
221
|
end
|
219
222
|
|
220
223
|
it 'scrubs the required parameters' do
|
221
|
-
expect(subject.call(
|
224
|
+
expect(subject.call(options)).to be_eql_hash_with_regexes(result)
|
222
225
|
end
|
223
226
|
end
|
224
227
|
end
|
@@ -249,7 +252,7 @@ describe Rollbar::Scrubbers::Params do
|
|
249
252
|
end
|
250
253
|
|
251
254
|
it 'scrubs the required parameters' do
|
252
|
-
expect(subject.call(
|
255
|
+
expect(subject.call(options)).to be_eql_hash_with_regexes(result)
|
253
256
|
end
|
254
257
|
end
|
255
258
|
end
|
@@ -4,15 +4,15 @@ require 'rollbar/scrubbers/url'
|
|
4
4
|
|
5
5
|
describe Rollbar::Scrubbers::URL do
|
6
6
|
let(:options) do
|
7
|
-
{
|
7
|
+
{
|
8
|
+
:url => url,
|
9
|
+
:scrub_fields => [:password, :secret],
|
8
10
|
:scrub_user => false,
|
9
11
|
:scrub_password => false,
|
10
12
|
:randomize_scrub_length => true
|
11
13
|
}
|
12
14
|
end
|
13
15
|
|
14
|
-
subject { described_class.new(options) }
|
15
|
-
|
16
16
|
describe '#call' do
|
17
17
|
context 'cannot scrub URLs' do
|
18
18
|
next if Rollbar::LanguageSupport.can_scrub_url?
|
@@ -20,7 +20,7 @@ describe Rollbar::Scrubbers::URL do
|
|
20
20
|
let(:url) { 'http://user:password@foo.com/some-interesting-path#fragment' }
|
21
21
|
|
22
22
|
it 'returns the URL without any change' do
|
23
|
-
expect(subject.call(
|
23
|
+
expect(subject.call(options)).to be_eql(url)
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
@@ -31,14 +31,14 @@ describe Rollbar::Scrubbers::URL do
|
|
31
31
|
let(:url) { 'http://user:password@foo.com/some-interesting-path#fragment' }
|
32
32
|
|
33
33
|
it 'returns the URL without any change' do
|
34
|
-
expect(subject.call(
|
34
|
+
expect(subject.call(options)).to be_eql(url)
|
35
35
|
end
|
36
36
|
|
37
37
|
context 'with arrays in params' do
|
38
38
|
let(:url) { 'http://user:password@foo.com/some-interesting-path?foo[]=1&foo[]=2' }
|
39
39
|
|
40
40
|
it 'returns the URL without any change' do
|
41
|
-
expect(subject.call(
|
41
|
+
expect(subject.call(options)).to be_eql(url)
|
42
42
|
end
|
43
43
|
end
|
44
44
|
end
|
@@ -46,6 +46,7 @@ describe Rollbar::Scrubbers::URL do
|
|
46
46
|
context 'scrubbing user and password' do
|
47
47
|
let(:options) do
|
48
48
|
{
|
49
|
+
:url => url,
|
49
50
|
:scrub_fields => [],
|
50
51
|
:scrub_password => true,
|
51
52
|
:scrub_user => true
|
@@ -57,7 +58,7 @@ describe Rollbar::Scrubbers::URL do
|
|
57
58
|
it 'returns the URL without any change' do
|
58
59
|
expected_url = /http:\/\/\*{3,8}:\*{3,8}@foo.com\/some-interesting\-path#fragment/
|
59
60
|
|
60
|
-
expect(subject.call(
|
61
|
+
expect(subject.call(options)).to match(expected_url)
|
61
62
|
end
|
62
63
|
end
|
63
64
|
|
@@ -67,7 +68,7 @@ describe Rollbar::Scrubbers::URL do
|
|
67
68
|
it 'returns the URL with some params filtered' do
|
68
69
|
expected_url = /http:\/\/foo.com\/some-interesting-path\?foo=bar&password=\*{3,8}&secret=\*{3,8}#fragment/
|
69
70
|
|
70
|
-
expect(subject.call(
|
71
|
+
expect(subject.call(options)).to match(expected_url)
|
71
72
|
end
|
72
73
|
|
73
74
|
context 'having array params' do
|
@@ -76,14 +77,16 @@ describe Rollbar::Scrubbers::URL do
|
|
76
77
|
it 'returns the URL with some params filtered' do
|
77
78
|
expected_url = /http:\/\/foo.com\/some-interesting-path\?foo=bar&password\[\]=\*{3,8}&password\[\]=\*{3,8}&secret=\*{3,8}#fragment/
|
78
79
|
|
79
|
-
expect(subject.call(
|
80
|
+
expect(subject.call(options)).to match(expected_url)
|
80
81
|
end
|
81
82
|
end
|
82
83
|
end
|
83
84
|
|
84
85
|
context 'with no-random scrub length' do
|
85
86
|
let(:options) do
|
86
|
-
{
|
87
|
+
{
|
88
|
+
:url => url,
|
89
|
+
:scrub_fields => [:password, :secret],
|
87
90
|
:scrub_user => false,
|
88
91
|
:scrub_password => false,
|
89
92
|
:randomize_scrub_length => false
|
@@ -95,15 +98,17 @@ describe Rollbar::Scrubbers::URL do
|
|
95
98
|
it 'scrubs with same length than the scrubbed param' do
|
96
99
|
expected_url = /http:\/\/foo.com\/some-interesting-path\?foo=bar&password=\*{#{password.length}}#fragment/
|
97
100
|
|
98
|
-
expect(subject.call(
|
101
|
+
expect(subject.call(options)).to match(expected_url)
|
99
102
|
end
|
100
103
|
end
|
101
104
|
|
102
105
|
context 'with malformed URL or not able to be parsed' do
|
103
106
|
let(:url) { '\this\is\not\a\valid\url' }
|
107
|
+
before { reconfigure_notifier }
|
104
108
|
|
105
109
|
it 'return the same url' do
|
106
|
-
expect(
|
110
|
+
expect(Rollbar.logger).to receive(:error).and_call_original
|
111
|
+
expect(subject.call(options)).to be_eql(url)
|
107
112
|
end
|
108
113
|
end
|
109
114
|
end
|
@@ -2,9 +2,10 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
unless RUBY_VERSION == '1.8.7'
|
4
4
|
require 'sidekiq'
|
5
|
-
require 'rollbar/sidekiq'
|
6
5
|
end
|
7
6
|
|
7
|
+
Rollbar.plugins.load!
|
8
|
+
|
8
9
|
describe Rollbar::Sidekiq::ClearScope, :reconfigure_notifier => false do
|
9
10
|
describe '#call' do
|
10
11
|
let(:middleware_block) { proc{} }
|
data/spec/rollbar/util_spec.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
1
3
|
require 'spec_helper'
|
2
4
|
|
3
5
|
require 'rollbar/util'
|
@@ -16,4 +18,63 @@ describe Rollbar::Util do
|
|
16
18
|
end
|
17
19
|
end
|
18
20
|
end
|
21
|
+
|
22
|
+
describe '.enforce_valid_utf8' do
|
23
|
+
# TODO(jon): all these tests should be removed since they are in
|
24
|
+
# in spec/rollbar/encoding/encoder.rb.
|
25
|
+
#
|
26
|
+
# This should just check that in payload with simple values and
|
27
|
+
# nested values are each one passed through Rollbar::Encoding.encode
|
28
|
+
context 'with utf8 string and ruby > 1.8' do
|
29
|
+
next unless String.instance_methods.include?(:force_encoding)
|
30
|
+
|
31
|
+
let(:payload) { { :foo => 'Изменение' } }
|
32
|
+
|
33
|
+
it 'just returns the same string' do
|
34
|
+
payload_copy = payload.clone
|
35
|
+
described_class.enforce_valid_utf8(payload_copy)
|
36
|
+
|
37
|
+
expect(payload_copy[:foo]).to be_eql('Изменение')
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'should replace invalid utf8 values' do
|
42
|
+
bad_key = force_to_ascii("inner \x92bad key")
|
43
|
+
|
44
|
+
payload = {
|
45
|
+
:bad_value => force_to_ascii("bad value 1\255"),
|
46
|
+
:bad_value_2 => force_to_ascii("bad\255 value 2"),
|
47
|
+
force_to_ascii("bad\255 key") => "good value",
|
48
|
+
:hash => {
|
49
|
+
:inner_bad_value => force_to_ascii("\255\255bad value 3"),
|
50
|
+
bad_key.to_sym => 'inner good value',
|
51
|
+
force_to_ascii("bad array key\255") => [
|
52
|
+
'good array value 1',
|
53
|
+
force_to_ascii("bad\255 array value 1\255"),
|
54
|
+
{
|
55
|
+
:inner_inner_bad => force_to_ascii("bad inner \255inner value")
|
56
|
+
}
|
57
|
+
]
|
58
|
+
}
|
59
|
+
}
|
60
|
+
|
61
|
+
|
62
|
+
payload_copy = payload.clone
|
63
|
+
described_class.enforce_valid_utf8(payload_copy)
|
64
|
+
|
65
|
+
payload_copy[:bad_value].should == "bad value 1"
|
66
|
+
payload_copy[:bad_value_2].should == "bad value 2"
|
67
|
+
payload_copy["bad key"].should == "good value"
|
68
|
+
payload_copy.keys.should_not include("bad\456 key")
|
69
|
+
payload_copy[:hash][:inner_bad_value].should == "bad value 3"
|
70
|
+
payload_copy[:hash][:"inner bad key"].should == 'inner good value'
|
71
|
+
payload_copy[:hash]["bad array key"].should == [
|
72
|
+
'good array value 1',
|
73
|
+
'bad array value 1',
|
74
|
+
{
|
75
|
+
:inner_inner_bad => 'bad inner inner value'
|
76
|
+
}
|
77
|
+
]
|
78
|
+
end
|
79
|
+
end
|
19
80
|
end
|
data/spec/rollbar_bc_spec.rb
CHANGED
@@ -23,7 +23,7 @@ describe Rollbar do
|
|
23
23
|
end
|
24
24
|
|
25
25
|
it 'should report simple messages' do
|
26
|
-
logger_mock.should_receive(:info).with('[Rollbar] Scheduling
|
26
|
+
logger_mock.should_receive(:info).with('[Rollbar] Scheduling item')
|
27
27
|
logger_mock.should_receive(:info).with('[Rollbar] Success')
|
28
28
|
|
29
29
|
Rollbar.report_message('Test message')
|
@@ -87,7 +87,7 @@ describe Rollbar do
|
|
87
87
|
|
88
88
|
it 'should report simple messages' do
|
89
89
|
allow(Rollbar).to receive(:notifier).and_return(notifier)
|
90
|
-
logger_mock.should_receive(:info).with('[Rollbar] Scheduling
|
90
|
+
logger_mock.should_receive(:info).with('[Rollbar] Scheduling item')
|
91
91
|
logger_mock.should_receive(:info).with('[Rollbar] Success')
|
92
92
|
Rollbar.report_message_with_request('Test message')
|
93
93
|
|
@@ -98,7 +98,7 @@ describe Rollbar do
|
|
98
98
|
it 'should report messages with request, person data and extra data' do
|
99
99
|
Rollbar.last_report = nil
|
100
100
|
|
101
|
-
logger_mock.should_receive(:info).with('[Rollbar] Scheduling
|
101
|
+
logger_mock.should_receive(:info).with('[Rollbar] Scheduling item')
|
102
102
|
logger_mock.should_receive(:info).with('[Rollbar] Success')
|
103
103
|
|
104
104
|
request_data = {
|
@@ -206,7 +206,7 @@ describe Rollbar do
|
|
206
206
|
if defined?(RUBY_ENGINE) && RUBY_ENGINE == 'jruby' && (not RUBY_VERSION =~ /^1\.9/)
|
207
207
|
it 'should work with an IO object as rack.errors' do
|
208
208
|
logger_mock.should_receive(:info).with('[Rollbar] Success')
|
209
|
-
|
209
|
+
|
210
210
|
request_data = {
|
211
211
|
:params => { :foo => 'bar' },
|
212
212
|
:url => 'http://localhost/',
|
@@ -217,15 +217,15 @@ describe Rollbar do
|
|
217
217
|
:method => 'GET',
|
218
218
|
:env => { :'rack.errors' => IO.new(2, File::WRONLY) },
|
219
219
|
}
|
220
|
-
|
220
|
+
|
221
221
|
person_data = {
|
222
222
|
:id => 1,
|
223
223
|
:username => 'test',
|
224
224
|
:email => 'test@example.com'
|
225
225
|
}
|
226
|
-
|
226
|
+
|
227
227
|
Rollbar.report_exception(@exception, request_data, person_data)
|
228
|
-
end
|
228
|
+
end
|
229
229
|
end
|
230
230
|
|
231
231
|
it 'should ignore ignored exception classes' do
|
@@ -313,7 +313,7 @@ describe Rollbar do
|
|
313
313
|
|
314
314
|
payload = nil
|
315
315
|
|
316
|
-
notifier.stub(:
|
316
|
+
notifier.stub(:schedule_item) do |*args|
|
317
317
|
payload = args[0]
|
318
318
|
end
|
319
319
|
|
@@ -338,7 +338,7 @@ describe Rollbar do
|
|
338
338
|
|
339
339
|
payload = nil
|
340
340
|
|
341
|
-
notifier.stub(:
|
341
|
+
notifier.stub(:schedule_item) do |*args|
|
342
342
|
payload = args[0]
|
343
343
|
end
|
344
344
|
|
@@ -359,7 +359,7 @@ describe Rollbar do
|
|
359
359
|
allow(Rollbar).to receive(:notifier).and_return(notifier)
|
360
360
|
payload = nil
|
361
361
|
|
362
|
-
notifier.stub(:
|
362
|
+
notifier.stub(:schedule_item) do |*args|
|
363
363
|
payload = args[0]
|
364
364
|
end
|
365
365
|
|
data/spec/rollbar_spec.rb
CHANGED
@@ -7,6 +7,12 @@ require 'redis'
|
|
7
7
|
require 'active_support/core_ext/object'
|
8
8
|
require 'active_support/json/encoding'
|
9
9
|
|
10
|
+
require 'rollbar/item'
|
11
|
+
begin
|
12
|
+
require 'rollbar/delay/sidekiq'
|
13
|
+
rescue LoadError
|
14
|
+
end
|
15
|
+
|
10
16
|
begin
|
11
17
|
require 'sucker_punch'
|
12
18
|
require 'sucker_punch/testing/inline'
|
@@ -109,6 +115,7 @@ describe Rollbar do
|
|
109
115
|
let(:scope) { { :bar => :foo } }
|
110
116
|
let(:configuration) do
|
111
117
|
config = Rollbar::Configuration.new
|
118
|
+
config.access_token = test_access_token
|
112
119
|
config.enabled = true
|
113
120
|
config
|
114
121
|
end
|
@@ -203,6 +210,7 @@ describe Rollbar do
|
|
203
210
|
:message => message,
|
204
211
|
:extra => extra
|
205
212
|
}
|
213
|
+
|
206
214
|
expect(handler1).to receive(:call).with(options).and_call_original
|
207
215
|
expect(handler2).not_to receive(:call)
|
208
216
|
expect(notifier).not_to receive(:report)
|
@@ -228,113 +236,6 @@ describe Rollbar do
|
|
228
236
|
end
|
229
237
|
end
|
230
238
|
|
231
|
-
context 'with transform handlers in configuration' do
|
232
|
-
let!(:notifier) { Rollbar::Notifier.new }
|
233
|
-
let(:scope) { { :bar => :foo } }
|
234
|
-
let(:configuration) do
|
235
|
-
config = Rollbar::Configuration.new
|
236
|
-
config.enabled = true
|
237
|
-
config.access_token = test_access_token
|
238
|
-
config
|
239
|
-
end
|
240
|
-
let(:message) { 'message' }
|
241
|
-
let(:exception) { Exception.new }
|
242
|
-
let(:extra) { {:foo => :bar } }
|
243
|
-
let(:level) { 'error' }
|
244
|
-
|
245
|
-
before do
|
246
|
-
notifier.configuration = configuration
|
247
|
-
notifier.scope!(scope)
|
248
|
-
end
|
249
|
-
|
250
|
-
context 'without mutation in payload' do
|
251
|
-
let(:handler) do
|
252
|
-
proc do |options|
|
253
|
-
|
254
|
-
end
|
255
|
-
end
|
256
|
-
|
257
|
-
before do
|
258
|
-
configuration.transform = handler
|
259
|
-
end
|
260
|
-
|
261
|
-
it 'calls the handler with the correct options' do
|
262
|
-
options = {
|
263
|
-
:level => level,
|
264
|
-
:scope => Rollbar::LazyStore.new(scope),
|
265
|
-
:exception => exception,
|
266
|
-
:message => message,
|
267
|
-
:extra => extra,
|
268
|
-
:payload => kind_of(Hash)
|
269
|
-
}
|
270
|
-
expect(handler).to receive(:call).with(options).and_call_original
|
271
|
-
expect(notifier).to receive(:schedule_payload).with(kind_of(Hash))
|
272
|
-
|
273
|
-
notifier.log(level, message, exception, extra)
|
274
|
-
end
|
275
|
-
end
|
276
|
-
|
277
|
-
context 'with mutation in payload' do
|
278
|
-
let(:new_payload) do
|
279
|
-
{
|
280
|
-
'access_token' => notifier.configuration.access_token,
|
281
|
-
'data' => {
|
282
|
-
}
|
283
|
-
}
|
284
|
-
end
|
285
|
-
let(:handler) do
|
286
|
-
proc do |options|
|
287
|
-
payload = options[:payload]
|
288
|
-
|
289
|
-
payload.replace(new_payload)
|
290
|
-
end
|
291
|
-
end
|
292
|
-
|
293
|
-
before do
|
294
|
-
configuration.transform = handler
|
295
|
-
end
|
296
|
-
|
297
|
-
it 'calls the handler with the correct options' do
|
298
|
-
options = {
|
299
|
-
:level => level,
|
300
|
-
:scope => Rollbar::LazyStore.new(scope),
|
301
|
-
:exception => exception,
|
302
|
-
:message => message,
|
303
|
-
:extra => extra,
|
304
|
-
:payload => kind_of(Hash)
|
305
|
-
}
|
306
|
-
expect(handler).to receive(:call).with(options).and_call_original
|
307
|
-
expect(notifier).to receive(:schedule_payload).with(new_payload)
|
308
|
-
|
309
|
-
notifier.log(level, message, exception, extra)
|
310
|
-
end
|
311
|
-
end
|
312
|
-
|
313
|
-
context 'with two handlers' do
|
314
|
-
let(:handler1) { proc { |options|} }
|
315
|
-
let(:handler2) { proc { |options|} }
|
316
|
-
|
317
|
-
before do
|
318
|
-
configuration.transform << handler1
|
319
|
-
configuration.transform << handler2
|
320
|
-
end
|
321
|
-
|
322
|
-
context 'and the first one fails' do
|
323
|
-
let(:exception) { StandardError.new('foo') }
|
324
|
-
let(:handler1) do
|
325
|
-
proc { |options| raise exception }
|
326
|
-
end
|
327
|
-
|
328
|
-
it 'doesnt call the second handler and logs the error' do
|
329
|
-
expect(handler2).not_to receive(:call)
|
330
|
-
expect(notifier).to receive(:log_error).with("[Rollbar] Error calling the `transform` hook: #{exception}")
|
331
|
-
|
332
|
-
notifier.log(level, message, exception, extra)
|
333
|
-
end
|
334
|
-
end
|
335
|
-
end
|
336
|
-
end
|
337
|
-
|
338
239
|
context 'debug/info/warning/error/critical' do
|
339
240
|
let(:exception) do
|
340
241
|
begin
|
@@ -524,438 +425,6 @@ describe Rollbar do
|
|
524
425
|
result.should == 'ignored'
|
525
426
|
end
|
526
427
|
end
|
527
|
-
|
528
|
-
context 'build_payload' do
|
529
|
-
context 'a basic payload' do
|
530
|
-
let(:extra_data) { {:key => 'value', :hash => {:inner_key => 'inner_value'}} }
|
531
|
-
let(:payload) { notifier.send(:build_payload, 'info', 'message', nil, extra_data) }
|
532
|
-
|
533
|
-
it 'should have the correct root-level keys' do
|
534
|
-
payload.keys.should match_array(['access_token', 'data'])
|
535
|
-
end
|
536
|
-
|
537
|
-
it 'should have the correct data keys' do
|
538
|
-
payload['data'].keys.should include(:timestamp, :environment, :level, :language, :framework, :server,
|
539
|
-
:notifier, :body)
|
540
|
-
end
|
541
|
-
|
542
|
-
it 'should have the correct notifier name and version' do
|
543
|
-
payload['data'][:notifier][:name].should == 'rollbar-gem'
|
544
|
-
payload['data'][:notifier][:version].should == Rollbar::VERSION
|
545
|
-
end
|
546
|
-
|
547
|
-
it 'should have the correct language and framework' do
|
548
|
-
payload['data'][:language].should == 'ruby'
|
549
|
-
payload['data'][:framework].should == Rollbar.configuration.framework
|
550
|
-
payload['data'][:framework].should match(/^Rails/)
|
551
|
-
end
|
552
|
-
|
553
|
-
it 'should have the correct server keys' do
|
554
|
-
payload['data'][:server].keys.should match_array([:host, :root, :pid])
|
555
|
-
end
|
556
|
-
|
557
|
-
it 'should have the correct level and message body' do
|
558
|
-
payload['data'][:level].should == 'info'
|
559
|
-
payload['data'][:body][:message][:body].should == 'message'
|
560
|
-
end
|
561
|
-
end
|
562
|
-
|
563
|
-
it 'should merge in a new key from payload_options' do
|
564
|
-
notifier.configure do |config|
|
565
|
-
config.payload_options = { :some_new_key => 'some new value' }
|
566
|
-
end
|
567
|
-
|
568
|
-
payload = notifier.send(:build_payload, 'info', 'message', nil, nil)
|
569
|
-
|
570
|
-
payload['data'][:some_new_key].should == 'some new value'
|
571
|
-
end
|
572
|
-
|
573
|
-
it 'should overwrite existing keys from payload_options' do
|
574
|
-
reconfigure_notifier
|
575
|
-
|
576
|
-
payload_options = {
|
577
|
-
:notifier => 'bad notifier',
|
578
|
-
:server => { :host => 'new host', :new_server_key => 'value' }
|
579
|
-
}
|
580
|
-
|
581
|
-
notifier.configure do |config|
|
582
|
-
config.payload_options = payload_options
|
583
|
-
end
|
584
|
-
|
585
|
-
payload = notifier.send(:build_payload, 'info', 'message', nil, nil)
|
586
|
-
|
587
|
-
payload['data'][:notifier].should == 'bad notifier'
|
588
|
-
payload['data'][:server][:host].should == 'new host'
|
589
|
-
payload['data'][:server][:root].should_not be_nil
|
590
|
-
payload['data'][:server][:new_server_key].should == 'value'
|
591
|
-
end
|
592
|
-
|
593
|
-
it 'should have default environment "unspecified"' do
|
594
|
-
Rollbar.unconfigure
|
595
|
-
payload = notifier.send(:build_payload, 'info', 'message', nil, nil)
|
596
|
-
payload['data'][:environment].should == 'unspecified'
|
597
|
-
end
|
598
|
-
|
599
|
-
it 'should have an overridden environment' do
|
600
|
-
Rollbar.configure do |config|
|
601
|
-
config.environment = 'overridden'
|
602
|
-
end
|
603
|
-
|
604
|
-
payload = notifier.send(:build_payload, 'info', 'message', nil, nil)
|
605
|
-
payload['data'][:environment].should == 'overridden'
|
606
|
-
end
|
607
|
-
|
608
|
-
it 'should not have custom data under default configuration' do
|
609
|
-
payload = notifier.send(:build_payload, 'info', 'message', nil, nil)
|
610
|
-
payload['data'][:body][:message][:extra].should be_nil
|
611
|
-
end
|
612
|
-
|
613
|
-
it 'should have custom message data when custom_data_method is configured' do
|
614
|
-
Rollbar.configure do |config|
|
615
|
-
config.custom_data_method = lambda { {:a => 1, :b => [2, 3, 4]} }
|
616
|
-
end
|
617
|
-
|
618
|
-
payload = notifier.send(:build_payload, 'info', 'message', nil, nil)
|
619
|
-
payload['data'][:body][:message][:extra].should_not be_nil
|
620
|
-
payload['data'][:body][:message][:extra][:a].should == 1
|
621
|
-
payload['data'][:body][:message][:extra][:b][2].should == 4
|
622
|
-
end
|
623
|
-
|
624
|
-
it 'should merge extra data into custom message data' do
|
625
|
-
custom_method = lambda do
|
626
|
-
{ :a => 1,
|
627
|
-
:b => [2, 3, 4],
|
628
|
-
:c => { :d => 'd', :e => 'e' },
|
629
|
-
:f => ['1', '2']
|
630
|
-
}
|
631
|
-
end
|
632
|
-
|
633
|
-
Rollbar.configure do |config|
|
634
|
-
config.custom_data_method = custom_method
|
635
|
-
end
|
636
|
-
|
637
|
-
payload = notifier.send(:build_payload, 'info', 'message', nil, {:c => {:e => 'g'}, :f => 'f'})
|
638
|
-
payload['data'][:body][:message][:extra].should_not be_nil
|
639
|
-
payload['data'][:body][:message][:extra][:a].should == 1
|
640
|
-
payload['data'][:body][:message][:extra][:b][2].should == 4
|
641
|
-
payload['data'][:body][:message][:extra][:c][:d].should == 'd'
|
642
|
-
payload['data'][:body][:message][:extra][:c][:e].should == 'g'
|
643
|
-
payload['data'][:body][:message][:extra][:f].should == 'f'
|
644
|
-
end
|
645
|
-
|
646
|
-
context 'with custom_data_method crashing' do
|
647
|
-
next unless defined?(SecureRandom) and SecureRandom.respond_to?(:uuid)
|
648
|
-
|
649
|
-
let(:crashing_exception) { StandardError.new }
|
650
|
-
let(:custom_method) { proc { raise crashing_exception } }
|
651
|
-
let(:extra) { { :foo => :bar } }
|
652
|
-
let(:custom_data_report) do
|
653
|
-
{ :_error_in_custom_data_method => SecureRandom.uuid }
|
654
|
-
end
|
655
|
-
let(:expected_extra) { extra.merge(custom_data_report) }
|
656
|
-
|
657
|
-
before do
|
658
|
-
notifier.configure do |config|
|
659
|
-
config.custom_data_method = custom_method
|
660
|
-
end
|
661
|
-
end
|
662
|
-
|
663
|
-
it 'doesnt crash the report' do
|
664
|
-
expect(notifier).to receive(:report_custom_data_error).once.and_return(custom_data_report)
|
665
|
-
payload = notifier.send(:build_payload, 'info', 'message', nil, extra)
|
666
|
-
|
667
|
-
expect(payload['data'][:body][:message][:extra]).to be_eql(expected_extra)
|
668
|
-
end
|
669
|
-
|
670
|
-
context 'and for some reason the safely.error returns a String' do
|
671
|
-
it 'returns an empty Hash' do
|
672
|
-
allow_any_instance_of(Rollbar::Notifier).to receive(:error).and_return('ignored')
|
673
|
-
|
674
|
-
payload = notifier.send(:build_payload, 'info', 'message', nil, extra)
|
675
|
-
|
676
|
-
expect(payload['data'][:body][:message][:extra]).to be_eql(extra)
|
677
|
-
end
|
678
|
-
end
|
679
|
-
end
|
680
|
-
|
681
|
-
it 'should include project_gem_paths' do
|
682
|
-
gems = Gem::Specification.map(&:name)
|
683
|
-
project_gems = ['rails']
|
684
|
-
project_gems << 'rspec' if gems.include?('rspec')
|
685
|
-
project_gems << 'rspec-core' if gems.include?('rspec-core')
|
686
|
-
|
687
|
-
notifier.configure do |config|
|
688
|
-
config.project_gems = project_gems
|
689
|
-
end
|
690
|
-
|
691
|
-
payload = notifier.send(:build_payload, 'info', 'message', nil, nil)
|
692
|
-
expect(payload['data'][:project_package_paths].count).to eq(project_gems.size)
|
693
|
-
end
|
694
|
-
|
695
|
-
it 'should include a code_version' do
|
696
|
-
notifier.configure do |config|
|
697
|
-
config.code_version = 'abcdef'
|
698
|
-
end
|
699
|
-
|
700
|
-
payload = notifier.send(:build_payload, 'info', 'message', nil, nil)
|
701
|
-
|
702
|
-
payload['data'][:code_version].should == 'abcdef'
|
703
|
-
end
|
704
|
-
|
705
|
-
it 'should have the right hostname' do
|
706
|
-
payload = notifier.send(:build_payload, 'info', 'message', nil, nil)
|
707
|
-
|
708
|
-
payload['data'][:server][:host].should == Socket.gethostname
|
709
|
-
end
|
710
|
-
|
711
|
-
it 'should have root and branch set when configured' do
|
712
|
-
configure
|
713
|
-
Rollbar.configure do |config|
|
714
|
-
config.root = '/path/to/root'
|
715
|
-
config.branch = 'master'
|
716
|
-
end
|
717
|
-
|
718
|
-
payload = notifier.send(:build_payload, 'info', 'message', nil, nil)
|
719
|
-
|
720
|
-
payload['data'][:server][:root].should == '/path/to/root'
|
721
|
-
payload['data'][:server][:branch].should == 'master'
|
722
|
-
end
|
723
|
-
|
724
|
-
context "with Redis instance in payload and ActiveSupport is enabled" do
|
725
|
-
let(:redis) { ::Redis.new }
|
726
|
-
let(:payload) do
|
727
|
-
{
|
728
|
-
:key => {
|
729
|
-
:value => redis
|
730
|
-
}
|
731
|
-
}
|
732
|
-
end
|
733
|
-
it 'dumps to JSON correctly' do
|
734
|
-
redis.set('foo', 'bar')
|
735
|
-
json = notifier.send(:dump_payload, payload)
|
736
|
-
|
737
|
-
expect(json).to be_kind_of(String)
|
738
|
-
end
|
739
|
-
end
|
740
|
-
end
|
741
|
-
|
742
|
-
context 'build_payload_body' do
|
743
|
-
let(:exception) do
|
744
|
-
begin
|
745
|
-
foo = bar
|
746
|
-
rescue => e
|
747
|
-
e
|
748
|
-
end
|
749
|
-
end
|
750
|
-
|
751
|
-
it 'should build a message body when no exception is passed in' do
|
752
|
-
body = notifier.send(:build_payload_body, 'message', nil, nil)
|
753
|
-
body[:message][:body].should == 'message'
|
754
|
-
body[:message][:extra].should be_nil
|
755
|
-
body[:trace].should be_nil
|
756
|
-
end
|
757
|
-
|
758
|
-
it 'should build a message body when no exception and extra data is passed in' do
|
759
|
-
body = notifier.send(:build_payload_body, 'message', nil, {:a => 'b'})
|
760
|
-
body[:message][:body].should == 'message'
|
761
|
-
body[:message][:extra].should == {:a => 'b'}
|
762
|
-
body[:trace].should be_nil
|
763
|
-
end
|
764
|
-
|
765
|
-
it 'should build an exception body when one is passed in' do
|
766
|
-
body = notifier.send(:build_payload_body, 'message', exception, nil)
|
767
|
-
body[:message].should be_nil
|
768
|
-
|
769
|
-
trace = body[:trace]
|
770
|
-
trace.should_not be_nil
|
771
|
-
trace[:extra].should be_nil
|
772
|
-
|
773
|
-
trace[:exception][:class].should_not be_nil
|
774
|
-
trace[:exception][:message].should_not be_nil
|
775
|
-
end
|
776
|
-
|
777
|
-
it 'should build an exception body when one is passed in along with extra data' do
|
778
|
-
body = notifier.send(:build_payload_body, 'message', exception, {:a => 'b'})
|
779
|
-
body[:message].should be_nil
|
780
|
-
|
781
|
-
trace = body[:trace]
|
782
|
-
trace.should_not be_nil
|
783
|
-
|
784
|
-
trace[:exception][:class].should_not be_nil
|
785
|
-
trace[:exception][:message].should_not be_nil
|
786
|
-
trace[:extra].should == {:a => 'b'}
|
787
|
-
end
|
788
|
-
end
|
789
|
-
|
790
|
-
context 'build_payload_body_exception' do
|
791
|
-
let(:exception) do
|
792
|
-
begin
|
793
|
-
foo = bar
|
794
|
-
rescue => e
|
795
|
-
e
|
796
|
-
end
|
797
|
-
end
|
798
|
-
|
799
|
-
after(:each) do
|
800
|
-
Rollbar.unconfigure
|
801
|
-
configure
|
802
|
-
end
|
803
|
-
|
804
|
-
it 'should build valid exception data' do
|
805
|
-
body = notifier.send(:build_payload_body_exception, nil, exception, nil)
|
806
|
-
body[:message].should be_nil
|
807
|
-
|
808
|
-
trace = body[:trace]
|
809
|
-
|
810
|
-
frames = trace[:frames]
|
811
|
-
frames.should be_a_kind_of(Array)
|
812
|
-
frames.each do |frame|
|
813
|
-
frame[:filename].should be_a_kind_of(String)
|
814
|
-
frame[:lineno].should be_a_kind_of(Fixnum)
|
815
|
-
if frame[:method]
|
816
|
-
frame[:method].should be_a_kind_of(String)
|
817
|
-
end
|
818
|
-
end
|
819
|
-
|
820
|
-
# should be NameError, but can be NoMethodError sometimes on rubinius 1.8
|
821
|
-
# http://yehudakatz.com/2010/01/02/the-craziest-fing-bug-ive-ever-seen/
|
822
|
-
trace[:exception][:class].should match(/^(NameError|NoMethodError)$/)
|
823
|
-
trace[:exception][:message].should match(/^(undefined local variable or method `bar'|undefined method `bar' on an instance of)/)
|
824
|
-
end
|
825
|
-
|
826
|
-
it 'should build exception data with a description' do
|
827
|
-
body = notifier.send(:build_payload_body_exception, 'exception description', exception, nil)
|
828
|
-
|
829
|
-
trace = body[:trace]
|
830
|
-
|
831
|
-
trace[:exception][:message].should match(/^(undefined local variable or method `bar'|undefined method `bar' on an instance of)/)
|
832
|
-
trace[:exception][:description].should == 'exception description'
|
833
|
-
end
|
834
|
-
|
835
|
-
it 'should build exception data with a description and extra data' do
|
836
|
-
extra_data = {:key => 'value', :hash => {:inner_key => 'inner_value'}}
|
837
|
-
body = notifier.send(:build_payload_body_exception, 'exception description', exception, extra_data)
|
838
|
-
|
839
|
-
trace = body[:trace]
|
840
|
-
|
841
|
-
trace[:exception][:message].should match(/^(undefined local variable or method `bar'|undefined method `bar' on an instance of)/)
|
842
|
-
trace[:exception][:description].should == 'exception description'
|
843
|
-
trace[:extra][:key].should == 'value'
|
844
|
-
trace[:extra][:hash].should == {:inner_key => 'inner_value'}
|
845
|
-
end
|
846
|
-
|
847
|
-
it 'should build exception data with a extra data' do
|
848
|
-
extra_data = {:key => 'value', :hash => {:inner_key => 'inner_value'}}
|
849
|
-
body = notifier.send(:build_payload_body_exception, nil, exception, extra_data)
|
850
|
-
|
851
|
-
trace = body[:trace]
|
852
|
-
|
853
|
-
trace[:exception][:message].should match(/^(undefined local variable or method `bar'|undefined method `bar' on an instance of)/)
|
854
|
-
trace[:extra][:key].should == 'value'
|
855
|
-
trace[:extra][:hash].should == {:inner_key => 'inner_value'}
|
856
|
-
end
|
857
|
-
|
858
|
-
context 'with nested exceptions' do
|
859
|
-
let(:crashing_code) do
|
860
|
-
proc do
|
861
|
-
begin
|
862
|
-
begin
|
863
|
-
fail CauseException.new('the cause')
|
864
|
-
rescue
|
865
|
-
fail StandardError.new('the error')
|
866
|
-
end
|
867
|
-
rescue => e
|
868
|
-
e
|
869
|
-
end
|
870
|
-
end
|
871
|
-
end
|
872
|
-
|
873
|
-
let(:rescued_exception) { crashing_code.call }
|
874
|
-
let(:message) { 'message' }
|
875
|
-
let(:extra) { {} }
|
876
|
-
|
877
|
-
context 'using ruby >= 2.1' do
|
878
|
-
next unless Exception.instance_methods.include?(:cause)
|
879
|
-
|
880
|
-
it 'sends the two exceptions in the trace_chain attribute' do
|
881
|
-
body = notifier.send(:build_payload_body_exception, message, rescued_exception, extra)
|
882
|
-
|
883
|
-
body[:trace].should be_nil
|
884
|
-
body[:trace_chain].should be_kind_of(Array)
|
885
|
-
|
886
|
-
chain = body[:trace_chain]
|
887
|
-
chain[0][:exception][:class].should match(/StandardError/)
|
888
|
-
chain[0][:exception][:message].should match(/the error/)
|
889
|
-
|
890
|
-
chain[1][:exception][:class].should match(/CauseException/)
|
891
|
-
chain[1][:exception][:message].should match(/the cause/)
|
892
|
-
end
|
893
|
-
|
894
|
-
it 'ignores the cause when it is not an Exception' do
|
895
|
-
exception_with_custom_cause = Exception.new('custom cause')
|
896
|
-
allow(exception_with_custom_cause).to receive(:cause) { "Foo" }
|
897
|
-
body = notifier.send(:build_payload_body_exception, message, exception_with_custom_cause, extra)
|
898
|
-
body[:trace].should_not be_nil
|
899
|
-
end
|
900
|
-
|
901
|
-
context 'with cyclic nested exceptions' do
|
902
|
-
let(:exception1) { Exception.new('exception1') }
|
903
|
-
let(:exception2) { Exception.new('exception2') }
|
904
|
-
|
905
|
-
before do
|
906
|
-
allow(exception1).to receive(:cause).and_return(exception2)
|
907
|
-
allow(exception2).to receive(:cause).and_return(exception1)
|
908
|
-
end
|
909
|
-
|
910
|
-
it 'doesnt loop for ever' do
|
911
|
-
body = notifier.send(:build_payload_body_exception, message, exception1, extra)
|
912
|
-
chain = body[:trace_chain]
|
913
|
-
|
914
|
-
expect(chain[0][:exception][:message]).to be_eql('exception1')
|
915
|
-
expect(chain[1][:exception][:message]).to be_eql('exception2')
|
916
|
-
end
|
917
|
-
end
|
918
|
-
end
|
919
|
-
|
920
|
-
context 'using ruby <= 2.1' do
|
921
|
-
next if Exception.instance_methods.include?(:cause)
|
922
|
-
|
923
|
-
it 'sends only the last exception in the trace attribute' do
|
924
|
-
body = notifier.send(:build_payload_body_exception, message, rescued_exception, extra)
|
925
|
-
|
926
|
-
body[:trace].should be_kind_of(Hash)
|
927
|
-
body[:trace_chain].should be_nil
|
928
|
-
|
929
|
-
body[:trace][:exception][:class].should match(/StandardError/)
|
930
|
-
body[:trace][:exception][:message].should match(/the error/)
|
931
|
-
end
|
932
|
-
end
|
933
|
-
end
|
934
|
-
end
|
935
|
-
|
936
|
-
context 'build_payload_body_message' do
|
937
|
-
it 'should build a message' do
|
938
|
-
body = notifier.send(:build_payload_body_message, 'message', nil)
|
939
|
-
body[:message][:body].should == 'message'
|
940
|
-
body[:trace].should be_nil
|
941
|
-
end
|
942
|
-
|
943
|
-
it 'should build a message with extra data' do
|
944
|
-
extra_data = {:key => 'value', :hash => {:inner_key => 'inner_value'}}
|
945
|
-
body = notifier.send(:build_payload_body_message, 'message', extra_data)
|
946
|
-
body[:message][:body].should == 'message'
|
947
|
-
body[:message][:extra][:key].should == 'value'
|
948
|
-
body[:message][:extra][:hash].should == {:inner_key => 'inner_value'}
|
949
|
-
end
|
950
|
-
|
951
|
-
it 'should build an empty message with extra data' do
|
952
|
-
extra_data = {:key => 'value', :hash => {:inner_key => 'inner_value'}}
|
953
|
-
body = notifier.send(:build_payload_body_message, nil, extra_data)
|
954
|
-
body[:message][:body].should == 'Empty message'
|
955
|
-
body[:message][:extra][:key].should == 'value'
|
956
|
-
body[:message][:extra][:hash].should == {:inner_key => 'inner_value'}
|
957
|
-
end
|
958
|
-
end
|
959
428
|
end
|
960
429
|
|
961
430
|
context 'reporting' do
|
@@ -1089,7 +558,7 @@ describe Rollbar do
|
|
1089
558
|
}
|
1090
559
|
|
1091
560
|
Rollbar.configure do |config|
|
1092
|
-
config.payload_options = {:person => person_data}
|
561
|
+
config.payload_options = { :person => person_data }
|
1093
562
|
config.ignored_person_ids += [1]
|
1094
563
|
end
|
1095
564
|
|
@@ -1168,7 +637,7 @@ describe Rollbar do
|
|
1168
637
|
it 'should report exception objects with no backtrace' do
|
1169
638
|
payload = nil
|
1170
639
|
|
1171
|
-
notifier.stub(:
|
640
|
+
notifier.stub(:schedule_item) do |*args|
|
1172
641
|
payload = args[0]
|
1173
642
|
end
|
1174
643
|
|
@@ -1208,7 +677,7 @@ describe Rollbar do
|
|
1208
677
|
it 'should report exception objects with nonstandard backtraces' do
|
1209
678
|
payload = nil
|
1210
679
|
|
1211
|
-
notifier.stub(:
|
680
|
+
notifier.stub(:schedule_item) do |*args|
|
1212
681
|
payload = args[0]
|
1213
682
|
end
|
1214
683
|
|
@@ -1228,7 +697,7 @@ describe Rollbar do
|
|
1228
697
|
it 'should report exceptions with a custom level' do
|
1229
698
|
payload = nil
|
1230
699
|
|
1231
|
-
notifier.stub(:
|
700
|
+
notifier.stub(:schedule_item) do |*args|
|
1232
701
|
payload = args[0]
|
1233
702
|
end
|
1234
703
|
|
@@ -1268,7 +737,7 @@ describe Rollbar do
|
|
1268
737
|
let(:user) { User.create(:email => 'email@example.com', :encrypted_password => '', :created_at => Time.now, :updated_at => Time.now) }
|
1269
738
|
|
1270
739
|
it 'should report simple messages' do
|
1271
|
-
logger_mock.should_receive(:info).with('[Rollbar] Scheduling
|
740
|
+
logger_mock.should_receive(:info).with('[Rollbar] Scheduling item')
|
1272
741
|
logger_mock.should_receive(:info).with('[Rollbar] Success')
|
1273
742
|
Rollbar.error('Test message')
|
1274
743
|
end
|
@@ -1324,7 +793,7 @@ describe Rollbar do
|
|
1324
793
|
end
|
1325
794
|
|
1326
795
|
it 'should report messages with request, person data and extra data' do
|
1327
|
-
logger_mock.should_receive(:info).with('[Rollbar] Scheduling
|
796
|
+
logger_mock.should_receive(:info).with('[Rollbar] Scheduling item')
|
1328
797
|
logger_mock.should_receive(:info).with('[Rollbar] Success')
|
1329
798
|
|
1330
799
|
request_data = {
|
@@ -1381,14 +850,14 @@ describe Rollbar do
|
|
1381
850
|
|
1382
851
|
it 'should send the payload over the network by default' do
|
1383
852
|
logger_mock.should_not_receive(:info).with('[Rollbar] Writing payload to file')
|
1384
|
-
logger_mock.should_receive(:info).with('[Rollbar] Sending
|
853
|
+
logger_mock.should_receive(:info).with('[Rollbar] Sending item').once
|
1385
854
|
logger_mock.should_receive(:info).with('[Rollbar] Success').once
|
1386
855
|
Rollbar.error(exception)
|
1387
856
|
end
|
1388
857
|
|
1389
858
|
it 'should save the payload to a file if set' do
|
1390
|
-
logger_mock.should_not_receive(:info).with('[Rollbar] Sending
|
1391
|
-
logger_mock.should_receive(:info).with('[Rollbar] Writing
|
859
|
+
logger_mock.should_not_receive(:info).with('[Rollbar] Sending item')
|
860
|
+
logger_mock.should_receive(:info).with('[Rollbar] Writing item to file').once
|
1392
861
|
logger_mock.should_receive(:info).with('[Rollbar] Success').once
|
1393
862
|
|
1394
863
|
filepath = ''
|
@@ -1434,8 +903,8 @@ describe Rollbar do
|
|
1434
903
|
let(:logger_mock) { double("Rails.logger").as_null_object }
|
1435
904
|
|
1436
905
|
it 'should send the payload using the default asynchronous handler girl_friday' do
|
1437
|
-
logger_mock.should_receive(:info).with('[Rollbar] Scheduling
|
1438
|
-
logger_mock.should_receive(:info).with('[Rollbar] Sending
|
906
|
+
logger_mock.should_receive(:info).with('[Rollbar] Scheduling item')
|
907
|
+
logger_mock.should_receive(:info).with('[Rollbar] Sending item')
|
1439
908
|
logger_mock.should_receive(:info).with('[Rollbar] Success')
|
1440
909
|
|
1441
910
|
Rollbar.configure do |config|
|
@@ -1453,14 +922,14 @@ describe Rollbar do
|
|
1453
922
|
|
1454
923
|
it 'should send the payload using a user-supplied asynchronous handler' do
|
1455
924
|
logger_mock.should_receive(:info).with('Custom async handler called')
|
1456
|
-
logger_mock.should_receive(:info).with('[Rollbar] Sending
|
925
|
+
logger_mock.should_receive(:info).with('[Rollbar] Sending item')
|
1457
926
|
logger_mock.should_receive(:info).with('[Rollbar] Success')
|
1458
927
|
|
1459
928
|
Rollbar.configure do |config|
|
1460
929
|
config.use_async = true
|
1461
930
|
config.async_handler = Proc.new { |payload|
|
1462
931
|
logger_mock.info 'Custom async handler called'
|
1463
|
-
Rollbar.
|
932
|
+
Rollbar.process_from_async_handler(payload)
|
1464
933
|
}
|
1465
934
|
end
|
1466
935
|
|
@@ -1476,7 +945,7 @@ describe Rollbar do
|
|
1476
945
|
# simulate previous gem version
|
1477
946
|
string_payload = Rollbar::JSON.dump(payload)
|
1478
947
|
|
1479
|
-
Rollbar.
|
948
|
+
Rollbar.process_from_async_handler(string_payload)
|
1480
949
|
end
|
1481
950
|
end
|
1482
951
|
|
@@ -1572,8 +1041,8 @@ describe Rollbar do
|
|
1572
1041
|
|
1573
1042
|
describe "#use_sucker_punch", :if => defined?(SuckerPunch) do
|
1574
1043
|
it "should send the payload to sucker_punch delayer" do
|
1575
|
-
logger_mock.should_receive(:info).with('[Rollbar] Scheduling
|
1576
|
-
logger_mock.should_receive(:info).with('[Rollbar] Sending
|
1044
|
+
logger_mock.should_receive(:info).with('[Rollbar] Scheduling item')
|
1045
|
+
logger_mock.should_receive(:info).with('[Rollbar] Sending item')
|
1577
1046
|
logger_mock.should_receive(:info).with('[Rollbar] Success')
|
1578
1047
|
|
1579
1048
|
Rollbar.configure do |config|
|
@@ -1635,119 +1104,6 @@ describe Rollbar do
|
|
1635
1104
|
end
|
1636
1105
|
end
|
1637
1106
|
|
1638
|
-
context 'enforce_valid_utf8' do
|
1639
|
-
# TODO(jon): all these tests should be removed since they are in
|
1640
|
-
# in spec/rollbar/encoding/encoder.rb.
|
1641
|
-
#
|
1642
|
-
# This should just check that in payload with simple values and
|
1643
|
-
# nested values are each one passed through Rollbar::Encoding.encode
|
1644
|
-
context 'with utf8 string and ruby > 1.8' do
|
1645
|
-
next unless String.instance_methods.include?(:force_encoding)
|
1646
|
-
|
1647
|
-
let(:payload) { { :foo => 'Изменение' } }
|
1648
|
-
|
1649
|
-
it 'just returns the same string' do
|
1650
|
-
payload_copy = payload.clone
|
1651
|
-
notifier.send(:enforce_valid_utf8, payload_copy)
|
1652
|
-
|
1653
|
-
expect(payload_copy[:foo]).to be_eql('Изменение')
|
1654
|
-
end
|
1655
|
-
end
|
1656
|
-
|
1657
|
-
it 'should replace invalid utf8 values' do
|
1658
|
-
bad_key = force_to_ascii("inner \x92bad key")
|
1659
|
-
|
1660
|
-
payload = {
|
1661
|
-
:bad_value => force_to_ascii("bad value 1\255"),
|
1662
|
-
:bad_value_2 => force_to_ascii("bad\255 value 2"),
|
1663
|
-
force_to_ascii("bad\255 key") => "good value",
|
1664
|
-
:hash => {
|
1665
|
-
:inner_bad_value => force_to_ascii("\255\255bad value 3"),
|
1666
|
-
bad_key.to_sym => 'inner good value',
|
1667
|
-
force_to_ascii("bad array key\255") => [
|
1668
|
-
'good array value 1',
|
1669
|
-
force_to_ascii("bad\255 array value 1\255"),
|
1670
|
-
{
|
1671
|
-
:inner_inner_bad => force_to_ascii("bad inner \255inner value")
|
1672
|
-
}
|
1673
|
-
]
|
1674
|
-
}
|
1675
|
-
}
|
1676
|
-
|
1677
|
-
|
1678
|
-
payload_copy = payload.clone
|
1679
|
-
notifier.send(:enforce_valid_utf8, payload_copy)
|
1680
|
-
|
1681
|
-
payload_copy[:bad_value].should == "bad value 1"
|
1682
|
-
payload_copy[:bad_value_2].should == "bad value 2"
|
1683
|
-
payload_copy["bad key"].should == "good value"
|
1684
|
-
payload_copy.keys.should_not include("bad\456 key")
|
1685
|
-
payload_copy[:hash][:inner_bad_value].should == "bad value 3"
|
1686
|
-
payload_copy[:hash][:"inner bad key"].should == 'inner good value'
|
1687
|
-
payload_copy[:hash]["bad array key"].should == [
|
1688
|
-
'good array value 1',
|
1689
|
-
'bad array value 1',
|
1690
|
-
{
|
1691
|
-
:inner_inner_bad => 'bad inner inner value'
|
1692
|
-
}
|
1693
|
-
]
|
1694
|
-
end
|
1695
|
-
end
|
1696
|
-
|
1697
|
-
context 'truncate_payload' do
|
1698
|
-
it 'should truncate all nested strings in the payload' do
|
1699
|
-
payload = {
|
1700
|
-
:truncated => '1234567',
|
1701
|
-
:not_truncated => '123456',
|
1702
|
-
:hash => {
|
1703
|
-
:inner_truncated => '123456789',
|
1704
|
-
:inner_not_truncated => '567',
|
1705
|
-
:array => ['12345678', '12', {:inner_inner => '123456789'}]
|
1706
|
-
}
|
1707
|
-
}
|
1708
|
-
|
1709
|
-
payload_copy = payload.clone
|
1710
|
-
notifier.send(:truncate_payload, payload_copy, 6)
|
1711
|
-
|
1712
|
-
payload_copy[:truncated].should == '123...'
|
1713
|
-
payload_copy[:not_truncated].should == '123456'
|
1714
|
-
payload_copy[:hash][:inner_truncated].should == '123...'
|
1715
|
-
payload_copy[:hash][:inner_not_truncated].should == '567'
|
1716
|
-
payload_copy[:hash][:array].should == ['123...', '12', {:inner_inner => '123...'}]
|
1717
|
-
end
|
1718
|
-
|
1719
|
-
it 'should truncate utf8 strings properly' do
|
1720
|
-
payload = {
|
1721
|
-
:truncated => 'Ŝǻмρļẻ śţяịņģ',
|
1722
|
-
:not_truncated => '123456',
|
1723
|
-
}
|
1724
|
-
|
1725
|
-
payload_copy = payload.clone
|
1726
|
-
notifier.send(:truncate_payload, payload_copy, 6)
|
1727
|
-
|
1728
|
-
payload_copy[:truncated].should == "Ŝǻм..."
|
1729
|
-
payload_copy[:not_truncated].should == '123456'
|
1730
|
-
end
|
1731
|
-
end
|
1732
|
-
|
1733
|
-
context 'server_data' do
|
1734
|
-
it 'should have the right hostname' do
|
1735
|
-
notifier.send(:server_data)[:host] == Socket.gethostname
|
1736
|
-
end
|
1737
|
-
|
1738
|
-
it 'should have root and branch set when configured' do
|
1739
|
-
configure
|
1740
|
-
Rollbar.configure do |config|
|
1741
|
-
config.root = '/path/to/root'
|
1742
|
-
config.branch = 'master'
|
1743
|
-
end
|
1744
|
-
|
1745
|
-
data = notifier.send(:server_data)
|
1746
|
-
data[:root].should == '/path/to/root'
|
1747
|
-
data[:branch].should == 'master'
|
1748
|
-
end
|
1749
|
-
end
|
1750
|
-
|
1751
1107
|
context "project_gems" do
|
1752
1108
|
it "should include gem paths for specified project gems in the payload" do
|
1753
1109
|
gems = ['rack', 'rspec-rails']
|
@@ -1762,7 +1118,7 @@ describe Rollbar do
|
|
1762
1118
|
gem_spec.gem_dir if gem_spec
|
1763
1119
|
end.compact
|
1764
1120
|
|
1765
|
-
data = notifier.send(:
|
1121
|
+
data = notifier.send(:build_item, 'info', 'test', nil, {})['data']
|
1766
1122
|
data[:project_package_paths].kind_of?(Array).should == true
|
1767
1123
|
data[:project_package_paths].length.should == gem_paths.length
|
1768
1124
|
|
@@ -1785,7 +1141,7 @@ describe Rollbar do
|
|
1785
1141
|
gem_paths.any?{|path| path.include? 'rollbar-gem'}.should == true
|
1786
1142
|
gem_paths.any?{|path| path.include? 'rspec-rails'}.should == true
|
1787
1143
|
|
1788
|
-
data = notifier.send(:
|
1144
|
+
data = notifier.send(:build_item, 'info', 'test', nil, {})['data']
|
1789
1145
|
data[:project_package_paths].kind_of?(Array).should == true
|
1790
1146
|
data[:project_package_paths].length.should == gem_paths.length
|
1791
1147
|
(data[:project_package_paths] - gem_paths).length.should == 0
|
@@ -1798,7 +1154,7 @@ describe Rollbar do
|
|
1798
1154
|
config.project_gems = gems
|
1799
1155
|
end
|
1800
1156
|
|
1801
|
-
data = notifier.send(:
|
1157
|
+
data = notifier.send(:build_item, 'info', 'test', nil, {})['data']
|
1802
1158
|
data[:project_package_paths].kind_of?(Array).should == true
|
1803
1159
|
data[:project_package_paths].length.should == 1
|
1804
1160
|
end
|
@@ -1881,7 +1237,7 @@ describe Rollbar do
|
|
1881
1237
|
config.logger = logger_mock
|
1882
1238
|
end
|
1883
1239
|
|
1884
|
-
logger_mock.should_receive(:info).with('[Rollbar] Sending
|
1240
|
+
logger_mock.should_receive(:info).with('[Rollbar] Sending item').once
|
1885
1241
|
logger_mock.should_receive(:info).with('[Rollbar] Success').once
|
1886
1242
|
scoped_notifier.send(:report_internal_error, exception)
|
1887
1243
|
end
|
@@ -1983,16 +1339,16 @@ describe Rollbar do
|
|
1983
1339
|
end
|
1984
1340
|
end
|
1985
1341
|
|
1986
|
-
describe '.
|
1342
|
+
describe '.process_item' do
|
1987
1343
|
context 'if there is an exception sending the payload' do
|
1988
1344
|
let(:exception) { StandardError.new('error message') }
|
1989
|
-
let(:payload) { { :foo => :bar } }
|
1345
|
+
let(:payload) { Rollbar::Item.build_with({ :foo => :bar }) }
|
1990
1346
|
|
1991
1347
|
it 'logs the error and the payload' do
|
1992
|
-
allow(Rollbar.notifier).to receive(:
|
1348
|
+
allow(Rollbar.notifier).to receive(:send_item).and_raise(exception)
|
1993
1349
|
expect(Rollbar.notifier).to receive(:log_error)
|
1994
1350
|
|
1995
|
-
expect { Rollbar.notifier.
|
1351
|
+
expect { Rollbar.notifier.process_item(payload) }.to raise_error(exception)
|
1996
1352
|
end
|
1997
1353
|
end
|
1998
1354
|
end
|
@@ -2002,7 +1358,7 @@ describe Rollbar do
|
|
2002
1358
|
let(:exception) { StandardError.new('the error') }
|
2003
1359
|
|
2004
1360
|
it 'raises anything and sends internal error' do
|
2005
|
-
allow(Rollbar.notifier).to receive(:
|
1361
|
+
allow(Rollbar.notifier).to receive(:process_item).and_raise(exception)
|
2006
1362
|
expect(Rollbar.notifier).to receive(:report_internal_error).with(exception)
|
2007
1363
|
|
2008
1364
|
expect do
|
@@ -2015,35 +1371,6 @@ describe Rollbar do
|
|
2015
1371
|
end
|
2016
1372
|
end
|
2017
1373
|
|
2018
|
-
describe '#custom_data' do
|
2019
|
-
before do
|
2020
|
-
Rollbar.configure do |config|
|
2021
|
-
config.custom_data_method = proc { raise 'this-will-raise' }
|
2022
|
-
end
|
2023
|
-
|
2024
|
-
expect_any_instance_of(Rollbar::Notifier).to receive(:error).and_return(report_data)
|
2025
|
-
end
|
2026
|
-
|
2027
|
-
context 'with uuid in reported data' do
|
2028
|
-
next unless defined?(SecureRandom) and SecureRandom.respond_to?(:uuid)
|
2029
|
-
|
2030
|
-
let(:report_data) { { :uuid => SecureRandom.uuid } }
|
2031
|
-
let(:expected_url) { "https://rollbar.com/instance/uuid?uuid=#{report_data[:uuid]}" }
|
2032
|
-
|
2033
|
-
it 'returns the uuid in :_error_in_custom_data_method' do
|
2034
|
-
expect(notifier.custom_data).to be_eql(:_error_in_custom_data_method => expected_url)
|
2035
|
-
end
|
2036
|
-
end
|
2037
|
-
|
2038
|
-
context 'without uuid in reported data' do
|
2039
|
-
let(:report_data) { { :some => 'other-data' } }
|
2040
|
-
|
2041
|
-
it 'returns the uuid in :_error_in_custom_data_method' do
|
2042
|
-
expect(notifier.custom_data).to be_eql({})
|
2043
|
-
end
|
2044
|
-
end
|
2045
|
-
end
|
2046
|
-
|
2047
1374
|
describe '.preconfigure'do
|
2048
1375
|
before do
|
2049
1376
|
Rollbar.unconfigure
|
@@ -2066,6 +1393,30 @@ describe Rollbar do
|
|
2066
1393
|
end
|
2067
1394
|
end
|
2068
1395
|
|
1396
|
+
context 'having timeout issues (for ruby > 1.9.3)' do
|
1397
|
+
before do
|
1398
|
+
skip if Rollbar::LanguageSupport.ruby_18? || Rollbar::LanguageSupport.ruby_19?
|
1399
|
+
end
|
1400
|
+
|
1401
|
+
let(:exception_class) do
|
1402
|
+
Rollbar::LanguageSupport.timeout_exceptions.first
|
1403
|
+
end
|
1404
|
+
let(:net_exception) do
|
1405
|
+
exception_class.new
|
1406
|
+
end
|
1407
|
+
|
1408
|
+
before do
|
1409
|
+
allow_any_instance_of(Net::HTTP).to receive(:request).and_raise(net_exception)
|
1410
|
+
end
|
1411
|
+
|
1412
|
+
it 'retries the request' do
|
1413
|
+
expect_any_instance_of(Net::HTTP).to receive(:request).exactly(3)
|
1414
|
+
expect(Rollbar.notifier).to receive(:report_internal_error).with(net_exception)
|
1415
|
+
|
1416
|
+
Rollbar.info('foo')
|
1417
|
+
end
|
1418
|
+
end
|
1419
|
+
|
2069
1420
|
# configure with some basic params
|
2070
1421
|
def configure
|
2071
1422
|
reconfigure_notifier
|