rollbar 2.8.3 → 3.6.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 +5 -5
- data/.codeclimate.yml +18 -0
- data/.github/pull_request_template.md +34 -0
- data/.github/workflows/ci.yml +67 -0
- data/.gitignore +3 -1
- data/.rubocop.yml +206 -7
- data/Appraisals +10 -10
- data/CHANGELOG.md +257 -3
- data/Gemfile +74 -13
- data/README.md +38 -833
- data/Rakefile +0 -0
- data/THANKS.md +1 -0
- data/data/rollbar.snippet.js +1 -1
- data/docs/configuration.md +64 -3
- data/docs/plugins.md +46 -0
- data/gemfiles/rails50.gemfile +56 -0
- data/gemfiles/rails51.gemfile +57 -0
- data/gemfiles/rails52.gemfile +56 -0
- data/gemfiles/rails60.gemfile +52 -0
- data/gemfiles/rails61.gemfile +52 -0
- data/gemfiles/rails70.gemfile +52 -0
- data/gemfiles/rails71.gemfile +52 -0
- data/lib/generators/rollbar/rollbar_generator.rb +24 -20
- data/lib/generators/rollbar/templates/{initializer.rb → initializer.erb} +19 -5
- data/lib/rails/rollbar_runner.rb +26 -22
- data/lib/rollbar/capistrano.rb +78 -38
- data/lib/rollbar/capistrano3.rb +62 -1
- data/lib/rollbar/capistrano_tasks.rb +166 -0
- data/lib/rollbar/configuration.rb +291 -71
- data/lib/rollbar/delay/active_job.rb +17 -0
- data/lib/rollbar/delay/delayed_job.rb +23 -0
- data/lib/rollbar/delay/girl_friday.rb +4 -9
- data/lib/rollbar/delay/resque.rb +3 -6
- data/lib/rollbar/delay/shoryuken.rb +36 -0
- data/lib/rollbar/delay/sidekiq.rb +6 -8
- data/lib/rollbar/delay/sucker_punch.rb +17 -22
- data/lib/rollbar/delay/thread.rb +74 -3
- data/lib/rollbar/deploy.rb +91 -0
- data/lib/rollbar/encoding/encoder.rb +22 -11
- data/lib/rollbar/encoding.rb +2 -7
- data/lib/rollbar/exception_reporter.rb +36 -12
- data/lib/rollbar/item/backtrace.rb +118 -0
- data/lib/rollbar/item/frame.rb +121 -0
- data/lib/rollbar/item/locals.rb +103 -0
- data/lib/rollbar/item.rb +314 -0
- data/lib/rollbar/js.rb +0 -28
- data/lib/rollbar/json.rb +7 -55
- data/lib/rollbar/language_support.rb +7 -19
- data/lib/rollbar/lazy_store.rb +8 -12
- data/lib/rollbar/logger.rb +71 -0
- data/lib/rollbar/logger_proxy.rb +18 -1
- data/lib/rollbar/middleware/js/json_value.rb +36 -0
- data/lib/rollbar/middleware/js.rb +297 -0
- data/lib/rollbar/middleware/rack/builder.rb +4 -4
- data/lib/rollbar/middleware/rack/test_session.rb +4 -4
- data/lib/rollbar/middleware/rack.rb +52 -0
- data/lib/rollbar/middleware/rails/rollbar.rb +19 -7
- data/lib/rollbar/middleware/rails/show_exceptions.rb +21 -9
- data/lib/rollbar/middleware/sinatra.rb +2 -40
- data/lib/rollbar/notifier/trace_with_bindings.rb +75 -0
- data/lib/rollbar/notifier.rb +913 -0
- data/lib/rollbar/plugin.rb +126 -0
- data/lib/rollbar/plugins/active_job.rb +54 -0
- data/lib/rollbar/plugins/basic_socket.rb +31 -0
- data/lib/rollbar/plugins/delayed_job/job_data.rb +50 -0
- data/lib/rollbar/plugins/delayed_job/plugin.rb +88 -0
- data/lib/rollbar/plugins/delayed_job.rb +12 -0
- data/lib/rollbar/plugins/error_context.rb +11 -0
- data/lib/rollbar/plugins/goalie.rb +65 -0
- data/lib/rollbar/plugins/rack.rb +18 -0
- data/lib/rollbar/plugins/rails/controller_methods.rb +56 -0
- data/lib/rollbar/plugins/rails/error_subscriber.rb +12 -0
- data/lib/rollbar/plugins/rails/railtie30.rb +18 -0
- data/lib/rollbar/plugins/rails/railtie32.rb +18 -0
- data/lib/rollbar/plugins/rails/railtie_mixin.rb +37 -0
- data/lib/rollbar/plugins/rails.rb +89 -0
- data/lib/rollbar/plugins/rake.rb +73 -0
- data/lib/rollbar/plugins/resque/failure.rb +39 -0
- data/lib/rollbar/plugins/resque.rb +11 -0
- data/lib/rollbar/plugins/sidekiq/plugin.rb +77 -0
- data/lib/rollbar/plugins/sidekiq.rb +37 -0
- data/lib/rollbar/plugins/thread.rb +14 -0
- data/lib/rollbar/plugins/validations.rb +45 -0
- data/lib/rollbar/plugins.rb +47 -0
- data/lib/rollbar/rails.rb +0 -1
- data/lib/rollbar/rake_tasks.rb +4 -66
- data/lib/rollbar/request_data_extractor.rb +157 -117
- data/lib/rollbar/rollbar_test.rb +38 -0
- data/lib/rollbar/scrubbers/params.rb +133 -0
- data/lib/rollbar/scrubbers/url.rb +90 -35
- data/lib/rollbar/scrubbers.rb +13 -0
- data/lib/rollbar/truncation/frames_strategy.rb +2 -1
- data/lib/rollbar/truncation/min_body_strategy.rb +3 -4
- data/lib/rollbar/truncation/mixin.rb +1 -1
- data/lib/rollbar/truncation/remove_any_key_strategy.rb +126 -0
- data/lib/rollbar/truncation/remove_extra_strategy.rb +37 -0
- data/lib/rollbar/truncation/remove_request_strategy.rb +21 -0
- data/lib/rollbar/truncation/strings_strategy.rb +6 -5
- data/lib/rollbar/truncation.rb +10 -4
- data/lib/rollbar/util/hash.rb +37 -6
- data/lib/rollbar/util/ip_anonymizer.rb +33 -0
- data/lib/rollbar/util/ip_obfuscator.rb +1 -1
- data/lib/rollbar/util.rb +101 -55
- data/lib/rollbar/version.rb +1 -1
- data/lib/rollbar.rb +91 -879
- data/lib/tasks/benchmark.rake +104 -0
- data/lib/tasks/tasks.rake +3 -3
- data/rollbar.gemspec +21 -32
- data/spec/support/rollbar_api.rb +67 -0
- metadata +78 -439
- data/.travis.yml +0 -155
- data/gemfiles/rails30.gemfile +0 -20
- data/gemfiles/rails31.gemfile +0 -16
- data/gemfiles/rails32.gemfile +0 -17
- data/gemfiles/rails40.gemfile +0 -17
- data/gemfiles/rails41.gemfile +0 -15
- data/gemfiles/rails42.gemfile +0 -15
- data/lib/rollbar/active_job.rb +0 -11
- 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/delayed_job.rb +0 -78
- data/lib/rollbar/encoding/legacy_encoder.rb +0 -20
- data/lib/rollbar/goalie.rb +0 -33
- data/lib/rollbar/js/frameworks/rails.rb +0 -29
- data/lib/rollbar/js/frameworks.rb +0 -6
- data/lib/rollbar/js/middleware.rb +0 -129
- data/lib/rollbar/js/version.rb +0 -5
- data/lib/rollbar/json/default.rb +0 -11
- data/lib/rollbar/json/oj.rb +0 -15
- data/lib/rollbar/rack.rb +0 -9
- data/lib/rollbar/rails/controller_methods.rb +0 -40
- data/lib/rollbar/railtie.rb +0 -46
- data/lib/rollbar/rake.rb +0 -38
- data/lib/rollbar/sidekiq.rb +0 -40
- data/lib/rollbar/tasks/rollbar.cap +0 -45
- data/spec/cacert.pem +0 -3988
- data/spec/controllers/home_controller_spec.rb +0 -455
- data/spec/delay/sidekiq_spec.rb +0 -61
- data/spec/delay/sucker_punch_spec.rb +0 -25
- data/spec/delayed/backend/test.rb +0 -139
- data/spec/delayed/serialization/test.rb +0 -0
- data/spec/dummyapp/.gitignore +0 -73
- data/spec/dummyapp/Rakefile +0 -7
- data/spec/dummyapp/app/assets/javascripts/application.js +0 -3
- data/spec/dummyapp/app/assets/stylesheets/application.css.scss +0 -37
- data/spec/dummyapp/app/controllers/application_controller.rb +0 -3
- data/spec/dummyapp/app/controllers/home_controller.rb +0 -60
- data/spec/dummyapp/app/controllers/users_controller.rb +0 -17
- data/spec/dummyapp/app/helpers/.gitkeep +0 -0
- data/spec/dummyapp/app/mailers/.gitkeep +0 -0
- data/spec/dummyapp/app/models/.gitkeep +0 -0
- data/spec/dummyapp/app/models/user.rb +0 -7
- data/spec/dummyapp/app/views/devise/registrations/edit.html.erb +0 -27
- data/spec/dummyapp/app/views/devise/registrations/new.html.erb +0 -20
- data/spec/dummyapp/app/views/devise/shared/_links.html.erb +0 -25
- data/spec/dummyapp/app/views/home/cause_exception.html.erb +0 -1
- data/spec/dummyapp/app/views/home/index.html.erb +0 -4
- data/spec/dummyapp/app/views/home/report_exception.html.erb +0 -1
- data/spec/dummyapp/app/views/js/test.html.erb +0 -1
- data/spec/dummyapp/app/views/layouts/_messages.html.erb +0 -5
- data/spec/dummyapp/app/views/layouts/_navigation.html.erb +0 -21
- data/spec/dummyapp/app/views/layouts/application.html.erb +0 -25
- data/spec/dummyapp/app/views/layouts/simple.html.erb +0 -18
- data/spec/dummyapp/app/views/users/index.html.erb +0 -8
- data/spec/dummyapp/app/views/users/show.html.erb +0 -3
- data/spec/dummyapp/config/application.rb +0 -59
- data/spec/dummyapp/config/boot.rb +0 -10
- data/spec/dummyapp/config/database.yml +0 -25
- data/spec/dummyapp/config/environment.rb +0 -5
- data/spec/dummyapp/config/environments/development.rb +0 -37
- data/spec/dummyapp/config/environments/production.rb +0 -67
- data/spec/dummyapp/config/environments/test.rb +0 -37
- data/spec/dummyapp/config/initializers/backtrace_silencers.rb +0 -7
- data/spec/dummyapp/config/initializers/inflections.rb +0 -15
- data/spec/dummyapp/config/initializers/mime_types.rb +0 -5
- data/spec/dummyapp/config/initializers/rollbar.rb +0 -23
- data/spec/dummyapp/config/initializers/secret_token.rb +0 -7
- data/spec/dummyapp/config/initializers/session_store.rb +0 -8
- data/spec/dummyapp/config/initializers/wrap_parameters.rb +0 -16
- data/spec/dummyapp/config/locales/devise.en.yml +0 -58
- data/spec/dummyapp/config/locales/en.yml +0 -5
- data/spec/dummyapp/config/routes.rb +0 -17
- data/spec/dummyapp/config.ru +0 -4
- data/spec/dummyapp/db/migrate/20121121184652_devise_create_users.rb +0 -46
- data/spec/dummyapp/db/migrate/20121121184654_add_name_to_users.rb +0 -5
- data/spec/dummyapp/db/schema.rb +0 -35
- data/spec/dummyapp/db/seeds.rb +0 -12
- data/spec/dummyapp/lib/assets/.gitkeep +0 -0
- data/spec/dummyapp/public/404.html +0 -26
- data/spec/dummyapp/public/422.html +0 -26
- data/spec/dummyapp/public/500.html +0 -25
- data/spec/dummyapp/public/favicon.ico +0 -0
- data/spec/dummyapp/script/rails +0 -6
- data/spec/fixtures/file1 +0 -1
- data/spec/fixtures/file2 +0 -1
- data/spec/fixtures/payloads/message.json +0 -25
- data/spec/fixtures/payloads/sample.trace.json +0 -275
- data/spec/fixtures/payloads/sample.trace_chain.json +0 -530
- data/spec/generators/rollbar/rollbar_generator_spec.rb +0 -24
- data/spec/requests/home_spec.rb +0 -49
- data/spec/rollbar/active_job_spec.rb +0 -33
- data/spec/rollbar/configuration_spec.rb +0 -24
- data/spec/rollbar/delay/girl_friday_spec.rb +0 -41
- data/spec/rollbar/delay/resque_spec.rb +0 -37
- data/spec/rollbar/delay/thread_spec.rb +0 -27
- data/spec/rollbar/delayed_job/job_data.rb +0 -35
- data/spec/rollbar/delayed_job_spec.rb +0 -90
- data/spec/rollbar/encoding/encoder_spec.rb +0 -63
- data/spec/rollbar/js/frameworks/rails_spec.rb +0 -19
- data/spec/rollbar/js/middleware_spec.rb +0 -162
- data/spec/rollbar/json/oj_spec.rb +0 -18
- data/spec/rollbar/json_spec.rb +0 -110
- data/spec/rollbar/lazy_store_spec.rb +0 -99
- data/spec/rollbar/logger_proxy_spec.rb +0 -34
- data/spec/rollbar/middleware/rack/builder_spec.rb +0 -151
- data/spec/rollbar/middleware/sinatra_spec.rb +0 -197
- data/spec/rollbar/rake_spec.rb +0 -34
- data/spec/rollbar/request_data_extractor_spec.rb +0 -82
- data/spec/rollbar/scrubbers/url_spec.rb +0 -111
- data/spec/rollbar/sidekiq_spec.rb +0 -90
- data/spec/rollbar/truncation/frames_strategy_spec.rb +0 -70
- data/spec/rollbar/truncation/min_body_strategy_spec.rb +0 -57
- data/spec/rollbar/truncation/strings_strategy_spec.rb +0 -89
- data/spec/rollbar/truncation_spec.rb +0 -27
- data/spec/rollbar/util/hash_spec.rb +0 -22
- data/spec/rollbar/util_spec.rb +0 -19
- data/spec/rollbar_bc_spec.rb +0 -380
- data/spec/rollbar_spec.rb +0 -2067
- data/spec/spec_helper.rb +0 -49
- data/spec/support/cause_exception.rb +0 -1
- data/spec/support/encoding_helpers.rb +0 -8
- data/spec/support/encodings/iso_8859_9 +0 -1
- data/spec/support/fixture_helpers.rb +0 -10
- data/spec/support/get_ip_raising.rb +0 -7
- data/spec/support/helpers.rb +0 -5
- data/spec/support/notifier_helpers.rb +0 -36
- data/spec/support/shared_contexts.rb +0 -12
data/spec/rollbar_spec.rb
DELETED
@@ -1,2067 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
require 'logger'
|
4
|
-
require 'socket'
|
5
|
-
require 'girl_friday'
|
6
|
-
require 'redis'
|
7
|
-
require 'active_support/core_ext/object'
|
8
|
-
require 'active_support/json/encoding'
|
9
|
-
|
10
|
-
begin
|
11
|
-
require 'sucker_punch'
|
12
|
-
require 'sucker_punch/testing/inline'
|
13
|
-
rescue LoadError
|
14
|
-
end
|
15
|
-
|
16
|
-
require 'spec_helper'
|
17
|
-
|
18
|
-
describe Rollbar do
|
19
|
-
let(:notifier) { Rollbar.notifier }
|
20
|
-
before do
|
21
|
-
Rollbar.unconfigure
|
22
|
-
configure
|
23
|
-
end
|
24
|
-
|
25
|
-
context 'when notifier has been used before configure it' do
|
26
|
-
before do
|
27
|
-
Rollbar.unconfigure
|
28
|
-
Rollbar.reset_notifier!
|
29
|
-
end
|
30
|
-
|
31
|
-
it 'is finally reset' do
|
32
|
-
Rollbar.log_debug('Testing notifier')
|
33
|
-
expect(Rollbar.error('error message')).to be_eql('disabled')
|
34
|
-
|
35
|
-
reconfigure_notifier
|
36
|
-
|
37
|
-
expect(Rollbar.error('error message')).not_to be_eql('disabled')
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
context 'Notifier' do
|
42
|
-
describe '#log' do
|
43
|
-
let(:exception) do
|
44
|
-
begin
|
45
|
-
foo = bar
|
46
|
-
rescue => e
|
47
|
-
e
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
let(:configuration) { Rollbar.configuration }
|
52
|
-
|
53
|
-
context 'executing a Thread before Rollbar is configured' do
|
54
|
-
before do
|
55
|
-
Rollbar.reset_notifier!
|
56
|
-
Rollbar.unconfigure
|
57
|
-
|
58
|
-
Thread.new {}
|
59
|
-
|
60
|
-
Rollbar.configure do |config|
|
61
|
-
config.access_token = 'my-access-token'
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
|
-
it 'sets correct configuration for Rollbar.notifier' do
|
66
|
-
expect(Rollbar.notifier.configuration.enabled).to be_truthy
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
it 'should report a simple message' do
|
71
|
-
expect(notifier).to receive(:report).with('error', 'test message', nil, nil)
|
72
|
-
notifier.log('error', 'test message')
|
73
|
-
end
|
74
|
-
|
75
|
-
it 'should report a simple message with extra data' do
|
76
|
-
extra_data = {:key => 'value', :hash => {:inner_key => 'inner_value'}}
|
77
|
-
|
78
|
-
expect(notifier).to receive(:report).with('error', 'test message', nil, extra_data)
|
79
|
-
notifier.log('error', 'test message', extra_data)
|
80
|
-
end
|
81
|
-
|
82
|
-
it 'should report an exception' do
|
83
|
-
expect(notifier).to receive(:report).with('error', nil, exception, nil)
|
84
|
-
notifier.log('error', exception)
|
85
|
-
end
|
86
|
-
|
87
|
-
it 'should report an exception with extra data' do
|
88
|
-
extra_data = {:key => 'value', :hash => {:inner_key => 'inner_value'}}
|
89
|
-
|
90
|
-
expect(notifier).to receive(:report).with('error', nil, exception, extra_data)
|
91
|
-
notifier.log('error', exception, extra_data)
|
92
|
-
end
|
93
|
-
|
94
|
-
it 'should report an exception with a description' do
|
95
|
-
expect(notifier).to receive(:report).with('error', 'exception description', exception, nil)
|
96
|
-
notifier.log('error', exception, 'exception description')
|
97
|
-
end
|
98
|
-
|
99
|
-
it 'should report an exception with a description and extra data' do
|
100
|
-
extra_data = {:key => 'value', :hash => {:inner_key => 'inner_value'}}
|
101
|
-
|
102
|
-
expect(notifier).to receive(:report).with('error', 'exception description', exception, extra_data)
|
103
|
-
notifier.log('error', exception, extra_data, 'exception description')
|
104
|
-
end
|
105
|
-
end
|
106
|
-
|
107
|
-
context 'with before_process handlers in configuration' do
|
108
|
-
let!(:notifier) { Rollbar::Notifier.new }
|
109
|
-
let(:scope) { { :bar => :foo } }
|
110
|
-
let(:configuration) do
|
111
|
-
config = Rollbar::Configuration.new
|
112
|
-
config.enabled = true
|
113
|
-
config
|
114
|
-
end
|
115
|
-
let(:message) { 'message' }
|
116
|
-
let(:exception) { Exception.new }
|
117
|
-
let(:extra) { {:foo => :bar } }
|
118
|
-
let(:level) { 'error' }
|
119
|
-
|
120
|
-
before do
|
121
|
-
notifier.configuration = configuration
|
122
|
-
notifier.scope!(scope)
|
123
|
-
end
|
124
|
-
|
125
|
-
context 'without raise Rollbar::Ignore' do
|
126
|
-
let(:handler) do
|
127
|
-
proc do |options|
|
128
|
-
|
129
|
-
end
|
130
|
-
end
|
131
|
-
|
132
|
-
before do
|
133
|
-
configuration.before_process = handler
|
134
|
-
end
|
135
|
-
|
136
|
-
it 'calls the handler with the correct options' do
|
137
|
-
options = {
|
138
|
-
:level => level,
|
139
|
-
:scope => Rollbar::LazyStore.new(scope),
|
140
|
-
:exception => exception,
|
141
|
-
:message => message,
|
142
|
-
:extra => extra
|
143
|
-
}
|
144
|
-
|
145
|
-
expect(handler).to receive(:call).with(options)
|
146
|
-
expect(notifier).to receive(:report).with(level, message, exception, extra)
|
147
|
-
|
148
|
-
notifier.log(level, message, exception, extra)
|
149
|
-
end
|
150
|
-
end
|
151
|
-
|
152
|
-
context 'raising Rollbar::Ignore in the handler' do
|
153
|
-
let(:handler) do
|
154
|
-
proc do |options|
|
155
|
-
raise Rollbar::Ignore
|
156
|
-
end
|
157
|
-
end
|
158
|
-
|
159
|
-
before do
|
160
|
-
configuration.before_process = handler
|
161
|
-
end
|
162
|
-
|
163
|
-
it "calls the handler with correct options and doesn't call #report" do
|
164
|
-
options = {
|
165
|
-
:level => level,
|
166
|
-
:scope => Rollbar::LazyStore.new(scope),
|
167
|
-
:exception => exception,
|
168
|
-
:message => message,
|
169
|
-
:extra => extra
|
170
|
-
}
|
171
|
-
expect(handler).to receive(:call).with(options).and_call_original
|
172
|
-
expect(notifier).not_to receive(:report)
|
173
|
-
|
174
|
-
result = notifier.log(level, message, exception, extra)
|
175
|
-
|
176
|
-
expect(result).to be_eql('ignored')
|
177
|
-
end
|
178
|
-
end
|
179
|
-
|
180
|
-
context 'with 2 handlers, raising Rollbar::Ignore in the first one' do
|
181
|
-
let(:handler1) do
|
182
|
-
proc do |options|
|
183
|
-
raise Rollbar::Ignore
|
184
|
-
end
|
185
|
-
end
|
186
|
-
|
187
|
-
let(:handler2) do
|
188
|
-
proc do |options|
|
189
|
-
|
190
|
-
end
|
191
|
-
end
|
192
|
-
|
193
|
-
before do
|
194
|
-
configuration.before_process << handler1
|
195
|
-
configuration.before_process << handler2
|
196
|
-
end
|
197
|
-
|
198
|
-
it "calls only the first handler and doesn't calls #report" do
|
199
|
-
options = {
|
200
|
-
:level => level,
|
201
|
-
:scope => Rollbar::LazyStore.new(scope),
|
202
|
-
:exception => exception,
|
203
|
-
:message => message,
|
204
|
-
:extra => extra
|
205
|
-
}
|
206
|
-
expect(handler1).to receive(:call).with(options).and_call_original
|
207
|
-
expect(handler2).not_to receive(:call)
|
208
|
-
expect(notifier).not_to receive(:report)
|
209
|
-
|
210
|
-
result = notifier.log(level, message, exception, extra)
|
211
|
-
|
212
|
-
expect(result).to be_eql('ignored')
|
213
|
-
end
|
214
|
-
|
215
|
-
context 'if the first handler fails' do
|
216
|
-
let(:exception) { StandardError.new('foo') }
|
217
|
-
let(:handler1) do
|
218
|
-
proc { |options| raise exception }
|
219
|
-
end
|
220
|
-
|
221
|
-
it 'doesnt call the second handler and logs the error' do
|
222
|
-
expect(handler2).not_to receive(:call)
|
223
|
-
expect(notifier).to receive(:log_error).with("[Rollbar] Error calling the `before_process` hook: #{exception}")
|
224
|
-
|
225
|
-
notifier.log(level, message, exception, extra)
|
226
|
-
end
|
227
|
-
end
|
228
|
-
end
|
229
|
-
end
|
230
|
-
|
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
|
238
|
-
end
|
239
|
-
let(:message) { 'message' }
|
240
|
-
let(:exception) { Exception.new }
|
241
|
-
let(:extra) { {:foo => :bar } }
|
242
|
-
let(:level) { 'error' }
|
243
|
-
|
244
|
-
before do
|
245
|
-
notifier.configuration = configuration
|
246
|
-
notifier.scope!(scope)
|
247
|
-
end
|
248
|
-
|
249
|
-
context 'without mutation in payload' do
|
250
|
-
let(:handler) do
|
251
|
-
proc do |options|
|
252
|
-
|
253
|
-
end
|
254
|
-
end
|
255
|
-
|
256
|
-
before do
|
257
|
-
configuration.transform = handler
|
258
|
-
end
|
259
|
-
|
260
|
-
it 'calls the handler with the correct options' do
|
261
|
-
options = {
|
262
|
-
:level => level,
|
263
|
-
:scope => Rollbar::LazyStore.new(scope),
|
264
|
-
:exception => exception,
|
265
|
-
:message => message,
|
266
|
-
:extra => extra,
|
267
|
-
:payload => kind_of(Hash)
|
268
|
-
}
|
269
|
-
expect(handler).to receive(:call).with(options).and_call_original
|
270
|
-
expect(notifier).to receive(:schedule_payload).with(kind_of(Hash))
|
271
|
-
|
272
|
-
notifier.log(level, message, exception, extra)
|
273
|
-
end
|
274
|
-
end
|
275
|
-
|
276
|
-
context 'with mutation in payload' do
|
277
|
-
let(:new_payload) do
|
278
|
-
{
|
279
|
-
'access_token' => notifier.configuration.access_token,
|
280
|
-
'data' => {
|
281
|
-
}
|
282
|
-
}
|
283
|
-
end
|
284
|
-
let(:handler) do
|
285
|
-
proc do |options|
|
286
|
-
payload = options[:payload]
|
287
|
-
|
288
|
-
payload.replace(new_payload)
|
289
|
-
end
|
290
|
-
end
|
291
|
-
|
292
|
-
before do
|
293
|
-
configuration.transform = handler
|
294
|
-
end
|
295
|
-
|
296
|
-
it 'calls the handler with the correct options' do
|
297
|
-
options = {
|
298
|
-
:level => level,
|
299
|
-
:scope => Rollbar::LazyStore.new(scope),
|
300
|
-
:exception => exception,
|
301
|
-
:message => message,
|
302
|
-
:extra => extra,
|
303
|
-
:payload => kind_of(Hash)
|
304
|
-
}
|
305
|
-
expect(handler).to receive(:call).with(options).and_call_original
|
306
|
-
expect(notifier).to receive(:schedule_payload).with(new_payload)
|
307
|
-
|
308
|
-
notifier.log(level, message, exception, extra)
|
309
|
-
end
|
310
|
-
end
|
311
|
-
|
312
|
-
context 'with two handlers' do
|
313
|
-
let(:handler1) { proc { |options|} }
|
314
|
-
let(:handler2) { proc { |options|} }
|
315
|
-
|
316
|
-
before do
|
317
|
-
configuration.transform << handler1
|
318
|
-
configuration.transform << handler2
|
319
|
-
end
|
320
|
-
|
321
|
-
context 'and the first one fails' do
|
322
|
-
let(:exception) { StandardError.new('foo') }
|
323
|
-
let(:handler1) do
|
324
|
-
proc { |options| raise exception }
|
325
|
-
end
|
326
|
-
|
327
|
-
it 'doesnt call the second handler and logs the error' do
|
328
|
-
expect(handler2).not_to receive(:call)
|
329
|
-
expect(notifier).to receive(:log_error).with("[Rollbar] Error calling the `transform` hook: #{exception}")
|
330
|
-
|
331
|
-
notifier.log(level, message, exception, extra)
|
332
|
-
end
|
333
|
-
end
|
334
|
-
end
|
335
|
-
end
|
336
|
-
|
337
|
-
context 'debug/info/warning/error/critical' do
|
338
|
-
let(:exception) do
|
339
|
-
begin
|
340
|
-
foo = bar
|
341
|
-
rescue => e
|
342
|
-
e
|
343
|
-
end
|
344
|
-
end
|
345
|
-
|
346
|
-
let(:extra_data) { {:key => 'value', :hash => {:inner_key => 'inner_value'}} }
|
347
|
-
|
348
|
-
it 'should report with a debug level' do
|
349
|
-
expect(notifier).to receive(:report).with('debug', nil, exception, nil)
|
350
|
-
notifier.debug(exception)
|
351
|
-
|
352
|
-
expect(notifier).to receive(:report).with('debug', 'description', exception, nil)
|
353
|
-
notifier.debug(exception, 'description')
|
354
|
-
|
355
|
-
expect(notifier).to receive(:report).with('debug', 'description', exception, extra_data)
|
356
|
-
notifier.debug(exception, 'description', extra_data)
|
357
|
-
end
|
358
|
-
|
359
|
-
it 'should report with an info level' do
|
360
|
-
expect(notifier).to receive(:report).with('info', nil, exception, nil)
|
361
|
-
notifier.info(exception)
|
362
|
-
|
363
|
-
expect(notifier).to receive(:report).with('info', 'description', exception, nil)
|
364
|
-
notifier.info(exception, 'description')
|
365
|
-
|
366
|
-
expect(notifier).to receive(:report).with('info', 'description', exception, extra_data)
|
367
|
-
notifier.info(exception, 'description', extra_data)
|
368
|
-
end
|
369
|
-
|
370
|
-
it 'should report with a warning level' do
|
371
|
-
expect(notifier).to receive(:report).with('warning', nil, exception, nil)
|
372
|
-
notifier.warning(exception)
|
373
|
-
|
374
|
-
expect(notifier).to receive(:report).with('warning', 'description', exception, nil)
|
375
|
-
notifier.warning(exception, 'description')
|
376
|
-
|
377
|
-
expect(notifier).to receive(:report).with('warning', 'description', exception, extra_data)
|
378
|
-
notifier.warning(exception, 'description', extra_data)
|
379
|
-
end
|
380
|
-
|
381
|
-
it 'should report with an error level' do
|
382
|
-
expect(notifier).to receive(:report).with('error', nil, exception, nil)
|
383
|
-
notifier.error(exception)
|
384
|
-
|
385
|
-
expect(notifier).to receive(:report).with('error', 'description', exception, nil)
|
386
|
-
notifier.error(exception, 'description')
|
387
|
-
|
388
|
-
expect(notifier).to receive(:report).with('error', 'description', exception, extra_data)
|
389
|
-
notifier.error(exception, 'description', extra_data)
|
390
|
-
end
|
391
|
-
|
392
|
-
it 'should report with a critical level' do
|
393
|
-
expect(notifier).to receive(:report).with('critical', nil, exception, nil)
|
394
|
-
notifier.critical(exception)
|
395
|
-
|
396
|
-
expect(notifier).to receive(:report).with('critical', 'description', exception, nil)
|
397
|
-
notifier.critical(exception, 'description')
|
398
|
-
|
399
|
-
expect(notifier).to receive(:report).with('critical', 'description', exception, extra_data)
|
400
|
-
notifier.critical(exception, 'description', extra_data)
|
401
|
-
end
|
402
|
-
end
|
403
|
-
|
404
|
-
context 'scope' do
|
405
|
-
it 'should create a new notifier object' do
|
406
|
-
notifier2 = notifier.scope
|
407
|
-
|
408
|
-
notifier2.should_not eq(notifier)
|
409
|
-
notifier2.should be_instance_of(Rollbar::Notifier)
|
410
|
-
end
|
411
|
-
|
412
|
-
it 'should create a copy of the parent notifier\'s configuration' do
|
413
|
-
notifier.configure do |config|
|
414
|
-
config.code_version = '123'
|
415
|
-
config.payload_options = {
|
416
|
-
:a => 'a',
|
417
|
-
:b => {:c => 'c'}
|
418
|
-
}
|
419
|
-
end
|
420
|
-
|
421
|
-
notifier2 = notifier.scope
|
422
|
-
|
423
|
-
notifier2.configuration.code_version.should == '123'
|
424
|
-
notifier2.configuration.should_not equal(notifier.configuration)
|
425
|
-
notifier2.configuration.payload_options.should_not equal(notifier.configuration.payload_options)
|
426
|
-
notifier2.configuration.payload_options.should == notifier.configuration.payload_options
|
427
|
-
notifier2.configuration.payload_options.should == {
|
428
|
-
:a => 'a',
|
429
|
-
:b => {:c => 'c'}
|
430
|
-
}
|
431
|
-
end
|
432
|
-
|
433
|
-
it 'should not modify any parent notifier configuration' do
|
434
|
-
configure
|
435
|
-
Rollbar.configuration.code_version.should be_nil
|
436
|
-
Rollbar.configuration.payload_options.should be_empty
|
437
|
-
|
438
|
-
notifier.configure do |config|
|
439
|
-
config.code_version = '123'
|
440
|
-
config.payload_options = {
|
441
|
-
:a => 'a',
|
442
|
-
:b => {:c => 'c'}
|
443
|
-
}
|
444
|
-
end
|
445
|
-
|
446
|
-
notifier2 = notifier.scope
|
447
|
-
|
448
|
-
notifier2.configure do |config|
|
449
|
-
config.payload_options[:c] = 'c'
|
450
|
-
end
|
451
|
-
|
452
|
-
notifier.configuration.payload_options[:c].should be_nil
|
453
|
-
|
454
|
-
notifier3 = notifier2.scope({
|
455
|
-
:b => {:c => 3, :d => 'd'}
|
456
|
-
})
|
457
|
-
|
458
|
-
notifier3.configure do |config|
|
459
|
-
config.code_version = '456'
|
460
|
-
end
|
461
|
-
|
462
|
-
notifier.configuration.code_version.should == '123'
|
463
|
-
notifier.configuration.payload_options.should == {
|
464
|
-
:a => 'a',
|
465
|
-
:b => {:c => 'c'}
|
466
|
-
}
|
467
|
-
notifier2.configuration.code_version.should == '123'
|
468
|
-
notifier2.configuration.payload_options.should == {
|
469
|
-
:a => 'a',
|
470
|
-
:b => {:c => 'c'},
|
471
|
-
:c => 'c'
|
472
|
-
}
|
473
|
-
notifier3.configuration.code_version.should == '456'
|
474
|
-
notifier3.configuration.payload_options.should == {
|
475
|
-
:a => 'a',
|
476
|
-
:b => {:c => 'c'},
|
477
|
-
:c => 'c'
|
478
|
-
}
|
479
|
-
|
480
|
-
Rollbar.configuration.code_version.should be_nil
|
481
|
-
Rollbar.configuration.payload_options.should be_empty
|
482
|
-
end
|
483
|
-
end
|
484
|
-
|
485
|
-
context 'report' do
|
486
|
-
let(:logger_mock) { double("Rails.logger").as_null_object }
|
487
|
-
|
488
|
-
before(:each) do
|
489
|
-
configure
|
490
|
-
Rollbar.configure do |config|
|
491
|
-
config.logger = logger_mock
|
492
|
-
end
|
493
|
-
end
|
494
|
-
|
495
|
-
after(:each) do
|
496
|
-
Rollbar.unconfigure
|
497
|
-
configure
|
498
|
-
end
|
499
|
-
|
500
|
-
it 'should reject input that doesn\'t contain an exception, message or extra data' do
|
501
|
-
expect(logger_mock).to receive(:error).with('[Rollbar] Tried to send a report with no message, exception or extra data.')
|
502
|
-
expect(notifier).not_to receive(:schedule_payload)
|
503
|
-
|
504
|
-
result = notifier.send(:report, 'info', nil, nil, nil)
|
505
|
-
result.should == 'error'
|
506
|
-
end
|
507
|
-
|
508
|
-
it 'should be ignored if the person is ignored' do
|
509
|
-
person_data = {
|
510
|
-
:id => 1,
|
511
|
-
:username => "test",
|
512
|
-
:email => "test@example.com"
|
513
|
-
}
|
514
|
-
|
515
|
-
notifier.configure do |config|
|
516
|
-
config.ignored_person_ids += [1]
|
517
|
-
config.payload_options = { :person => person_data }
|
518
|
-
end
|
519
|
-
|
520
|
-
expect(notifier).not_to receive(:schedule_payload)
|
521
|
-
|
522
|
-
result = notifier.send(:report, 'info', 'message', nil, nil)
|
523
|
-
result.should == 'ignored'
|
524
|
-
end
|
525
|
-
end
|
526
|
-
|
527
|
-
context 'build_payload' do
|
528
|
-
context 'a basic payload' do
|
529
|
-
let(:extra_data) { {:key => 'value', :hash => {:inner_key => 'inner_value'}} }
|
530
|
-
let(:payload) { notifier.send(:build_payload, 'info', 'message', nil, extra_data) }
|
531
|
-
|
532
|
-
it 'should have the correct root-level keys' do
|
533
|
-
payload.keys.should match_array(['access_token', 'data'])
|
534
|
-
end
|
535
|
-
|
536
|
-
it 'should have the correct data keys' do
|
537
|
-
payload['data'].keys.should include(:timestamp, :environment, :level, :language, :framework, :server,
|
538
|
-
:notifier, :body)
|
539
|
-
end
|
540
|
-
|
541
|
-
it 'should have the correct notifier name and version' do
|
542
|
-
payload['data'][:notifier][:name].should == 'rollbar-gem'
|
543
|
-
payload['data'][:notifier][:version].should == Rollbar::VERSION
|
544
|
-
end
|
545
|
-
|
546
|
-
it 'should have the correct language and framework' do
|
547
|
-
payload['data'][:language].should == 'ruby'
|
548
|
-
payload['data'][:framework].should == Rollbar.configuration.framework
|
549
|
-
payload['data'][:framework].should match(/^Rails/)
|
550
|
-
end
|
551
|
-
|
552
|
-
it 'should have the correct server keys' do
|
553
|
-
payload['data'][:server].keys.should match_array([:host, :root, :pid])
|
554
|
-
end
|
555
|
-
|
556
|
-
it 'should have the correct level and message body' do
|
557
|
-
payload['data'][:level].should == 'info'
|
558
|
-
payload['data'][:body][:message][:body].should == 'message'
|
559
|
-
end
|
560
|
-
end
|
561
|
-
|
562
|
-
it 'should merge in a new key from payload_options' do
|
563
|
-
notifier.configure do |config|
|
564
|
-
config.payload_options = { :some_new_key => 'some new value' }
|
565
|
-
end
|
566
|
-
|
567
|
-
payload = notifier.send(:build_payload, 'info', 'message', nil, nil)
|
568
|
-
|
569
|
-
payload['data'][:some_new_key].should == 'some new value'
|
570
|
-
end
|
571
|
-
|
572
|
-
it 'should overwrite existing keys from payload_options' do
|
573
|
-
reconfigure_notifier
|
574
|
-
|
575
|
-
payload_options = {
|
576
|
-
:notifier => 'bad notifier',
|
577
|
-
:server => { :host => 'new host', :new_server_key => 'value' }
|
578
|
-
}
|
579
|
-
|
580
|
-
notifier.configure do |config|
|
581
|
-
config.payload_options = payload_options
|
582
|
-
end
|
583
|
-
|
584
|
-
payload = notifier.send(:build_payload, 'info', 'message', nil, nil)
|
585
|
-
|
586
|
-
payload['data'][:notifier].should == 'bad notifier'
|
587
|
-
payload['data'][:server][:host].should == 'new host'
|
588
|
-
payload['data'][:server][:root].should_not be_nil
|
589
|
-
payload['data'][:server][:new_server_key].should == 'value'
|
590
|
-
end
|
591
|
-
|
592
|
-
it 'should have default environment "unspecified"' do
|
593
|
-
Rollbar.unconfigure
|
594
|
-
payload = notifier.send(:build_payload, 'info', 'message', nil, nil)
|
595
|
-
payload['data'][:environment].should == 'unspecified'
|
596
|
-
end
|
597
|
-
|
598
|
-
it 'should have an overridden environment' do
|
599
|
-
Rollbar.configure do |config|
|
600
|
-
config.environment = 'overridden'
|
601
|
-
end
|
602
|
-
|
603
|
-
payload = notifier.send(:build_payload, 'info', 'message', nil, nil)
|
604
|
-
payload['data'][:environment].should == 'overridden'
|
605
|
-
end
|
606
|
-
|
607
|
-
it 'should not have custom data under default configuration' do
|
608
|
-
payload = notifier.send(:build_payload, 'info', 'message', nil, nil)
|
609
|
-
payload['data'][:body][:message][:extra].should be_nil
|
610
|
-
end
|
611
|
-
|
612
|
-
it 'should have custom message data when custom_data_method is configured' do
|
613
|
-
Rollbar.configure do |config|
|
614
|
-
config.custom_data_method = lambda { {:a => 1, :b => [2, 3, 4]} }
|
615
|
-
end
|
616
|
-
|
617
|
-
payload = notifier.send(:build_payload, 'info', 'message', nil, nil)
|
618
|
-
payload['data'][:body][:message][:extra].should_not be_nil
|
619
|
-
payload['data'][:body][:message][:extra][:a].should == 1
|
620
|
-
payload['data'][:body][:message][:extra][:b][2].should == 4
|
621
|
-
end
|
622
|
-
|
623
|
-
it 'should merge extra data into custom message data' do
|
624
|
-
custom_method = lambda do
|
625
|
-
{ :a => 1,
|
626
|
-
:b => [2, 3, 4],
|
627
|
-
:c => { :d => 'd', :e => 'e' },
|
628
|
-
:f => ['1', '2']
|
629
|
-
}
|
630
|
-
end
|
631
|
-
|
632
|
-
Rollbar.configure do |config|
|
633
|
-
config.custom_data_method = custom_method
|
634
|
-
end
|
635
|
-
|
636
|
-
payload = notifier.send(:build_payload, 'info', 'message', nil, {:c => {:e => 'g'}, :f => 'f'})
|
637
|
-
payload['data'][:body][:message][:extra].should_not be_nil
|
638
|
-
payload['data'][:body][:message][:extra][:a].should == 1
|
639
|
-
payload['data'][:body][:message][:extra][:b][2].should == 4
|
640
|
-
payload['data'][:body][:message][:extra][:c][:d].should == 'd'
|
641
|
-
payload['data'][:body][:message][:extra][:c][:e].should == 'g'
|
642
|
-
payload['data'][:body][:message][:extra][:f].should == 'f'
|
643
|
-
end
|
644
|
-
|
645
|
-
context 'with custom_data_method crashing' do
|
646
|
-
next unless defined?(SecureRandom) and SecureRandom.respond_to?(:uuid)
|
647
|
-
|
648
|
-
let(:crashing_exception) { StandardError.new }
|
649
|
-
let(:custom_method) { proc { raise crashing_exception } }
|
650
|
-
let(:extra) { { :foo => :bar } }
|
651
|
-
let(:custom_data_report) do
|
652
|
-
{ :_error_in_custom_data_method => SecureRandom.uuid }
|
653
|
-
end
|
654
|
-
let(:expected_extra) { extra.merge(custom_data_report) }
|
655
|
-
|
656
|
-
before do
|
657
|
-
notifier.configure do |config|
|
658
|
-
config.custom_data_method = custom_method
|
659
|
-
end
|
660
|
-
end
|
661
|
-
|
662
|
-
it 'doesnt crash the report' do
|
663
|
-
expect(notifier).to receive(:report_custom_data_error).once.and_return(custom_data_report)
|
664
|
-
payload = notifier.send(:build_payload, 'info', 'message', nil, extra)
|
665
|
-
|
666
|
-
expect(payload['data'][:body][:message][:extra]).to be_eql(expected_extra)
|
667
|
-
end
|
668
|
-
|
669
|
-
context 'and for some reason the safely.error returns a String' do
|
670
|
-
it 'returns an empty Hash' do
|
671
|
-
allow_any_instance_of(Rollbar::Notifier).to receive(:error).and_return('ignored')
|
672
|
-
|
673
|
-
payload = notifier.send(:build_payload, 'info', 'message', nil, extra)
|
674
|
-
|
675
|
-
expect(payload['data'][:body][:message][:extra]).to be_eql(extra)
|
676
|
-
end
|
677
|
-
end
|
678
|
-
end
|
679
|
-
|
680
|
-
it 'should include project_gem_paths' do
|
681
|
-
notifier.configure do |config|
|
682
|
-
config.project_gems = ['rails', 'rspec']
|
683
|
-
end
|
684
|
-
|
685
|
-
payload = notifier.send(:build_payload, 'info', 'message', nil, nil)
|
686
|
-
|
687
|
-
expect(payload['data'][:project_package_paths].count).to eq 2
|
688
|
-
end
|
689
|
-
|
690
|
-
it 'should include a code_version' do
|
691
|
-
notifier.configure do |config|
|
692
|
-
config.code_version = 'abcdef'
|
693
|
-
end
|
694
|
-
|
695
|
-
payload = notifier.send(:build_payload, 'info', 'message', nil, nil)
|
696
|
-
|
697
|
-
payload['data'][:code_version].should == 'abcdef'
|
698
|
-
end
|
699
|
-
|
700
|
-
it 'should have the right hostname' do
|
701
|
-
payload = notifier.send(:build_payload, 'info', 'message', nil, nil)
|
702
|
-
|
703
|
-
payload['data'][:server][:host].should == Socket.gethostname
|
704
|
-
end
|
705
|
-
|
706
|
-
it 'should have root and branch set when configured' do
|
707
|
-
configure
|
708
|
-
Rollbar.configure do |config|
|
709
|
-
config.root = '/path/to/root'
|
710
|
-
config.branch = 'master'
|
711
|
-
end
|
712
|
-
|
713
|
-
payload = notifier.send(:build_payload, 'info', 'message', nil, nil)
|
714
|
-
|
715
|
-
payload['data'][:server][:root].should == '/path/to/root'
|
716
|
-
payload['data'][:server][:branch].should == 'master'
|
717
|
-
end
|
718
|
-
|
719
|
-
context "with Redis instance in payload and ActiveSupport is enabled" do
|
720
|
-
let(:redis) { ::Redis.new }
|
721
|
-
let(:payload) do
|
722
|
-
{
|
723
|
-
:key => {
|
724
|
-
:value => redis
|
725
|
-
}
|
726
|
-
}
|
727
|
-
end
|
728
|
-
it 'dumps to JSON correctly' do
|
729
|
-
redis.set('foo', 'bar')
|
730
|
-
json = notifier.send(:dump_payload, payload)
|
731
|
-
|
732
|
-
expect(json).to be_kind_of(String)
|
733
|
-
end
|
734
|
-
end
|
735
|
-
end
|
736
|
-
|
737
|
-
context 'build_payload_body' do
|
738
|
-
let(:exception) do
|
739
|
-
begin
|
740
|
-
foo = bar
|
741
|
-
rescue => e
|
742
|
-
e
|
743
|
-
end
|
744
|
-
end
|
745
|
-
|
746
|
-
it 'should build a message body when no exception is passed in' do
|
747
|
-
body = notifier.send(:build_payload_body, 'message', nil, nil)
|
748
|
-
body[:message][:body].should == 'message'
|
749
|
-
body[:message][:extra].should be_nil
|
750
|
-
body[:trace].should be_nil
|
751
|
-
end
|
752
|
-
|
753
|
-
it 'should build a message body when no exception and extra data is passed in' do
|
754
|
-
body = notifier.send(:build_payload_body, 'message', nil, {:a => 'b'})
|
755
|
-
body[:message][:body].should == 'message'
|
756
|
-
body[:message][:extra].should == {:a => 'b'}
|
757
|
-
body[:trace].should be_nil
|
758
|
-
end
|
759
|
-
|
760
|
-
it 'should build an exception body when one is passed in' do
|
761
|
-
body = notifier.send(:build_payload_body, 'message', exception, nil)
|
762
|
-
body[:message].should be_nil
|
763
|
-
|
764
|
-
trace = body[:trace]
|
765
|
-
trace.should_not be_nil
|
766
|
-
trace[:extra].should be_nil
|
767
|
-
|
768
|
-
trace[:exception][:class].should_not be_nil
|
769
|
-
trace[:exception][:message].should_not be_nil
|
770
|
-
end
|
771
|
-
|
772
|
-
it 'should build an exception body when one is passed in along with extra data' do
|
773
|
-
body = notifier.send(:build_payload_body, 'message', exception, {:a => 'b'})
|
774
|
-
body[:message].should be_nil
|
775
|
-
|
776
|
-
trace = body[:trace]
|
777
|
-
trace.should_not be_nil
|
778
|
-
|
779
|
-
trace[:exception][:class].should_not be_nil
|
780
|
-
trace[:exception][:message].should_not be_nil
|
781
|
-
trace[:extra].should == {:a => 'b'}
|
782
|
-
end
|
783
|
-
end
|
784
|
-
|
785
|
-
context 'build_payload_body_exception' do
|
786
|
-
let(:exception) do
|
787
|
-
begin
|
788
|
-
foo = bar
|
789
|
-
rescue => e
|
790
|
-
e
|
791
|
-
end
|
792
|
-
end
|
793
|
-
|
794
|
-
after(:each) do
|
795
|
-
Rollbar.unconfigure
|
796
|
-
configure
|
797
|
-
end
|
798
|
-
|
799
|
-
it 'should build valid exception data' do
|
800
|
-
body = notifier.send(:build_payload_body_exception, nil, exception, nil)
|
801
|
-
body[:message].should be_nil
|
802
|
-
|
803
|
-
trace = body[:trace]
|
804
|
-
|
805
|
-
frames = trace[:frames]
|
806
|
-
frames.should be_a_kind_of(Array)
|
807
|
-
frames.each do |frame|
|
808
|
-
frame[:filename].should be_a_kind_of(String)
|
809
|
-
frame[:lineno].should be_a_kind_of(Fixnum)
|
810
|
-
if frame[:method]
|
811
|
-
frame[:method].should be_a_kind_of(String)
|
812
|
-
end
|
813
|
-
end
|
814
|
-
|
815
|
-
# should be NameError, but can be NoMethodError sometimes on rubinius 1.8
|
816
|
-
# http://yehudakatz.com/2010/01/02/the-craziest-fing-bug-ive-ever-seen/
|
817
|
-
trace[:exception][:class].should match(/^(NameError|NoMethodError)$/)
|
818
|
-
trace[:exception][:message].should match(/^(undefined local variable or method `bar'|undefined method `bar' on an instance of)/)
|
819
|
-
end
|
820
|
-
|
821
|
-
it 'should build exception data with a description' do
|
822
|
-
body = notifier.send(:build_payload_body_exception, 'exception description', exception, nil)
|
823
|
-
|
824
|
-
trace = body[:trace]
|
825
|
-
|
826
|
-
trace[:exception][:message].should match(/^(undefined local variable or method `bar'|undefined method `bar' on an instance of)/)
|
827
|
-
trace[:exception][:description].should == 'exception description'
|
828
|
-
end
|
829
|
-
|
830
|
-
it 'should build exception data with a description and extra data' do
|
831
|
-
extra_data = {:key => 'value', :hash => {:inner_key => 'inner_value'}}
|
832
|
-
body = notifier.send(:build_payload_body_exception, 'exception description', exception, extra_data)
|
833
|
-
|
834
|
-
trace = body[:trace]
|
835
|
-
|
836
|
-
trace[:exception][:message].should match(/^(undefined local variable or method `bar'|undefined method `bar' on an instance of)/)
|
837
|
-
trace[:exception][:description].should == 'exception description'
|
838
|
-
trace[:extra][:key].should == 'value'
|
839
|
-
trace[:extra][:hash].should == {:inner_key => 'inner_value'}
|
840
|
-
end
|
841
|
-
|
842
|
-
it 'should build exception data with a extra data' do
|
843
|
-
extra_data = {:key => 'value', :hash => {:inner_key => 'inner_value'}}
|
844
|
-
body = notifier.send(:build_payload_body_exception, nil, exception, extra_data)
|
845
|
-
|
846
|
-
trace = body[:trace]
|
847
|
-
|
848
|
-
trace[:exception][:message].should match(/^(undefined local variable or method `bar'|undefined method `bar' on an instance of)/)
|
849
|
-
trace[:extra][:key].should == 'value'
|
850
|
-
trace[:extra][:hash].should == {:inner_key => 'inner_value'}
|
851
|
-
end
|
852
|
-
|
853
|
-
context 'with nested exceptions' do
|
854
|
-
let(:crashing_code) do
|
855
|
-
proc do
|
856
|
-
begin
|
857
|
-
begin
|
858
|
-
fail CauseException.new('the cause')
|
859
|
-
rescue
|
860
|
-
fail StandardError.new('the error')
|
861
|
-
end
|
862
|
-
rescue => e
|
863
|
-
e
|
864
|
-
end
|
865
|
-
end
|
866
|
-
end
|
867
|
-
|
868
|
-
let(:rescued_exception) { crashing_code.call }
|
869
|
-
let(:message) { 'message' }
|
870
|
-
let(:extra) { {} }
|
871
|
-
|
872
|
-
context 'using ruby >= 2.1' do
|
873
|
-
next unless Exception.instance_methods.include?(:cause)
|
874
|
-
|
875
|
-
it 'sends the two exceptions in the trace_chain attribute' do
|
876
|
-
body = notifier.send(:build_payload_body_exception, message, rescued_exception, extra)
|
877
|
-
|
878
|
-
body[:trace].should be_nil
|
879
|
-
body[:trace_chain].should be_kind_of(Array)
|
880
|
-
|
881
|
-
chain = body[:trace_chain]
|
882
|
-
chain[0][:exception][:class].should match(/StandardError/)
|
883
|
-
chain[0][:exception][:message].should match(/the error/)
|
884
|
-
|
885
|
-
chain[1][:exception][:class].should match(/CauseException/)
|
886
|
-
chain[1][:exception][:message].should match(/the cause/)
|
887
|
-
end
|
888
|
-
|
889
|
-
it 'ignores the cause when it is not an Exception' do
|
890
|
-
exception_with_custom_cause = Exception.new('custom cause')
|
891
|
-
allow(exception_with_custom_cause).to receive(:cause) { "Foo" }
|
892
|
-
body = notifier.send(:build_payload_body_exception, message, exception_with_custom_cause, extra)
|
893
|
-
body[:trace].should_not be_nil
|
894
|
-
end
|
895
|
-
|
896
|
-
context 'with cyclic nested exceptions' do
|
897
|
-
let(:exception1) { Exception.new('exception1') }
|
898
|
-
let(:exception2) { Exception.new('exception2') }
|
899
|
-
|
900
|
-
before do
|
901
|
-
allow(exception1).to receive(:cause).and_return(exception2)
|
902
|
-
allow(exception2).to receive(:cause).and_return(exception1)
|
903
|
-
end
|
904
|
-
|
905
|
-
it 'doesnt loop for ever' do
|
906
|
-
body = notifier.send(:build_payload_body_exception, message, exception1, extra)
|
907
|
-
chain = body[:trace_chain]
|
908
|
-
|
909
|
-
expect(chain[0][:exception][:message]).to be_eql('exception1')
|
910
|
-
expect(chain[1][:exception][:message]).to be_eql('exception2')
|
911
|
-
end
|
912
|
-
end
|
913
|
-
end
|
914
|
-
|
915
|
-
context 'using ruby <= 2.1' do
|
916
|
-
next if Exception.instance_methods.include?(:cause)
|
917
|
-
|
918
|
-
it 'sends only the last exception in the trace attribute' do
|
919
|
-
body = notifier.send(:build_payload_body_exception, message, rescued_exception, extra)
|
920
|
-
|
921
|
-
body[:trace].should be_kind_of(Hash)
|
922
|
-
body[:trace_chain].should be_nil
|
923
|
-
|
924
|
-
body[:trace][:exception][:class].should match(/StandardError/)
|
925
|
-
body[:trace][:exception][:message].should match(/the error/)
|
926
|
-
end
|
927
|
-
end
|
928
|
-
end
|
929
|
-
end
|
930
|
-
|
931
|
-
context 'build_payload_body_message' do
|
932
|
-
it 'should build a message' do
|
933
|
-
body = notifier.send(:build_payload_body_message, 'message', nil)
|
934
|
-
body[:message][:body].should == 'message'
|
935
|
-
body[:trace].should be_nil
|
936
|
-
end
|
937
|
-
|
938
|
-
it 'should build a message with extra data' do
|
939
|
-
extra_data = {:key => 'value', :hash => {:inner_key => 'inner_value'}}
|
940
|
-
body = notifier.send(:build_payload_body_message, 'message', extra_data)
|
941
|
-
body[:message][:body].should == 'message'
|
942
|
-
body[:message][:extra][:key].should == 'value'
|
943
|
-
body[:message][:extra][:hash].should == {:inner_key => 'inner_value'}
|
944
|
-
end
|
945
|
-
|
946
|
-
it 'should build an empty message with extra data' do
|
947
|
-
extra_data = {:key => 'value', :hash => {:inner_key => 'inner_value'}}
|
948
|
-
body = notifier.send(:build_payload_body_message, nil, extra_data)
|
949
|
-
body[:message][:body].should == 'Empty message'
|
950
|
-
body[:message][:extra][:key].should == 'value'
|
951
|
-
body[:message][:extra][:hash].should == {:inner_key => 'inner_value'}
|
952
|
-
end
|
953
|
-
end
|
954
|
-
end
|
955
|
-
|
956
|
-
context 'reporting' do
|
957
|
-
let(:exception) do
|
958
|
-
begin
|
959
|
-
foo = bar
|
960
|
-
rescue => e
|
961
|
-
e
|
962
|
-
end
|
963
|
-
end
|
964
|
-
|
965
|
-
let(:logger_mock) { double("Rails.logger").as_null_object }
|
966
|
-
let(:user) { User.create(:email => 'email@example.com', :encrypted_password => '', :created_at => Time.now, :updated_at => Time.now) }
|
967
|
-
|
968
|
-
before(:each) do
|
969
|
-
configure
|
970
|
-
Rollbar.configure do |config|
|
971
|
-
config.logger = logger_mock
|
972
|
-
end
|
973
|
-
end
|
974
|
-
|
975
|
-
after(:each) do
|
976
|
-
Rollbar.unconfigure
|
977
|
-
configure
|
978
|
-
end
|
979
|
-
|
980
|
-
it 'should report exceptions without person or request data' do
|
981
|
-
logger_mock.should_receive(:info).with('[Rollbar] Success')
|
982
|
-
Rollbar.error(exception)
|
983
|
-
end
|
984
|
-
|
985
|
-
it 'should not report anything when disabled' do
|
986
|
-
logger_mock.should_not_receive(:info).with('[Rollbar] Success')
|
987
|
-
|
988
|
-
Rollbar.configure do |config|
|
989
|
-
config.enabled = false
|
990
|
-
end
|
991
|
-
|
992
|
-
Rollbar.error(exception).should == 'disabled'
|
993
|
-
end
|
994
|
-
|
995
|
-
it 'should report exceptions without person or request data' do
|
996
|
-
logger_mock.should_receive(:info).with('[Rollbar] Success')
|
997
|
-
Rollbar.error(exception)
|
998
|
-
end
|
999
|
-
|
1000
|
-
it 'should be enabled when freshly configured' do
|
1001
|
-
Rollbar.configuration.enabled.should == true
|
1002
|
-
end
|
1003
|
-
|
1004
|
-
it 'should not be enabled when not configured' do
|
1005
|
-
Rollbar.unconfigure
|
1006
|
-
|
1007
|
-
Rollbar.configuration.enabled.should be_nil
|
1008
|
-
Rollbar.error(exception).should == 'disabled'
|
1009
|
-
end
|
1010
|
-
|
1011
|
-
it 'should stay disabled if configure is called again' do
|
1012
|
-
Rollbar.unconfigure
|
1013
|
-
|
1014
|
-
# configure once, setting enabled to false.
|
1015
|
-
Rollbar.configure do |config|
|
1016
|
-
config.enabled = false
|
1017
|
-
end
|
1018
|
-
|
1019
|
-
# now configure again (perhaps to change some other values)
|
1020
|
-
Rollbar.configure do |config| end
|
1021
|
-
|
1022
|
-
Rollbar.configuration.enabled.should == false
|
1023
|
-
Rollbar.error(exception).should == 'disabled'
|
1024
|
-
end
|
1025
|
-
|
1026
|
-
context 'using :use_exception_level_filters option as true' do
|
1027
|
-
it 'sends the correct filtered level' do
|
1028
|
-
Rollbar.configure do |config|
|
1029
|
-
config.exception_level_filters = { 'NameError' => 'warning' }
|
1030
|
-
end
|
1031
|
-
|
1032
|
-
Rollbar.error(exception, :use_exception_level_filters => true)
|
1033
|
-
expect(Rollbar.last_report[:level]).to be_eql('warning')
|
1034
|
-
end
|
1035
|
-
|
1036
|
-
it 'ignore ignored exception classes' do
|
1037
|
-
Rollbar.configure do |config|
|
1038
|
-
config.exception_level_filters = { 'NameError' => 'ignore' }
|
1039
|
-
end
|
1040
|
-
|
1041
|
-
logger_mock.should_not_receive(:info)
|
1042
|
-
logger_mock.should_not_receive(:warn)
|
1043
|
-
logger_mock.should_not_receive(:error)
|
1044
|
-
|
1045
|
-
Rollbar.error(exception, :use_exception_level_filters => true)
|
1046
|
-
end
|
1047
|
-
end
|
1048
|
-
|
1049
|
-
context 'if not using :use_exception_level_filters option' do
|
1050
|
-
it 'sends the level defined by the used method' do
|
1051
|
-
Rollbar.configure do |config|
|
1052
|
-
config.exception_level_filters = { 'NameError' => 'warning' }
|
1053
|
-
end
|
1054
|
-
|
1055
|
-
Rollbar.error(exception)
|
1056
|
-
expect(Rollbar.last_report[:level]).to be_eql('error')
|
1057
|
-
end
|
1058
|
-
|
1059
|
-
it 'ignore ignored exception classes' do
|
1060
|
-
Rollbar.configure do |config|
|
1061
|
-
config.exception_level_filters = { 'NameError' => 'ignore' }
|
1062
|
-
end
|
1063
|
-
|
1064
|
-
Rollbar.error(exception)
|
1065
|
-
|
1066
|
-
expect(Rollbar.last_report[:level]).to be_eql('error')
|
1067
|
-
end
|
1068
|
-
end
|
1069
|
-
|
1070
|
-
# Skip jruby 1.9+ (https://github.com/jruby/jruby/issues/2373)
|
1071
|
-
if defined?(RUBY_ENGINE) && RUBY_ENGINE == 'jruby' && (not RUBY_VERSION =~ /^1\.9/)
|
1072
|
-
it "should work with an IO object as rack.errors" do
|
1073
|
-
logger_mock.should_receive(:info).with('[Rollbar] Success')
|
1074
|
-
|
1075
|
-
Rollbar.error(exception, :env => { :"rack.errors" => IO.new(2, File::WRONLY) })
|
1076
|
-
end
|
1077
|
-
end
|
1078
|
-
|
1079
|
-
it 'should ignore ignored persons' do
|
1080
|
-
person_data = {
|
1081
|
-
:id => 1,
|
1082
|
-
:username => "test",
|
1083
|
-
:email => "test@example.com"
|
1084
|
-
}
|
1085
|
-
|
1086
|
-
Rollbar.configure do |config|
|
1087
|
-
config.payload_options = {:person => person_data}
|
1088
|
-
config.ignored_person_ids += [1]
|
1089
|
-
end
|
1090
|
-
|
1091
|
-
logger_mock.should_not_receive(:info)
|
1092
|
-
logger_mock.should_not_receive(:warn)
|
1093
|
-
logger_mock.should_not_receive(:error)
|
1094
|
-
|
1095
|
-
Rollbar.error(exception)
|
1096
|
-
end
|
1097
|
-
|
1098
|
-
it 'should not ignore non-ignored persons' do
|
1099
|
-
person_data = {
|
1100
|
-
:id => 1,
|
1101
|
-
:username => "test",
|
1102
|
-
:email => "test@example.com"
|
1103
|
-
}
|
1104
|
-
Rollbar.configure do |config|
|
1105
|
-
config.payload_options = { :person => person_data }
|
1106
|
-
config.ignored_person_ids += [1]
|
1107
|
-
end
|
1108
|
-
|
1109
|
-
Rollbar.last_report = nil
|
1110
|
-
|
1111
|
-
Rollbar.error(exception)
|
1112
|
-
Rollbar.last_report.should be_nil
|
1113
|
-
|
1114
|
-
person_data = {
|
1115
|
-
:id => 2,
|
1116
|
-
:username => "test2",
|
1117
|
-
:email => "test2@example.com"
|
1118
|
-
}
|
1119
|
-
|
1120
|
-
new_options = {
|
1121
|
-
:person => person_data
|
1122
|
-
}
|
1123
|
-
|
1124
|
-
Rollbar.scoped(new_options) do
|
1125
|
-
Rollbar.error(exception)
|
1126
|
-
end
|
1127
|
-
|
1128
|
-
Rollbar.last_report.should_not be_nil
|
1129
|
-
end
|
1130
|
-
|
1131
|
-
it 'should allow callables to set exception filtered level' do
|
1132
|
-
callable_mock = double
|
1133
|
-
saved_filters = Rollbar.configuration.exception_level_filters
|
1134
|
-
|
1135
|
-
Rollbar.configure do |config|
|
1136
|
-
config.exception_level_filters = { 'NameError' => callable_mock }
|
1137
|
-
end
|
1138
|
-
|
1139
|
-
callable_mock.should_receive(:call).with(exception).at_least(:once).and_return("info")
|
1140
|
-
logger_mock.should_receive(:info)
|
1141
|
-
logger_mock.should_not_receive(:warn)
|
1142
|
-
logger_mock.should_not_receive(:error)
|
1143
|
-
|
1144
|
-
Rollbar.error(exception, :use_exception_level_filters => true)
|
1145
|
-
end
|
1146
|
-
|
1147
|
-
it 'should not report exceptions when silenced' do
|
1148
|
-
expect_any_instance_of(Rollbar::Notifier).to_not receive(:schedule_payload)
|
1149
|
-
|
1150
|
-
begin
|
1151
|
-
test_var = 1
|
1152
|
-
Rollbar.silenced do
|
1153
|
-
test_var = 2
|
1154
|
-
raise
|
1155
|
-
end
|
1156
|
-
rescue => e
|
1157
|
-
Rollbar.error(e)
|
1158
|
-
end
|
1159
|
-
|
1160
|
-
test_var.should == 2
|
1161
|
-
end
|
1162
|
-
|
1163
|
-
it 'should report exception objects with no backtrace' do
|
1164
|
-
payload = nil
|
1165
|
-
|
1166
|
-
notifier.stub(:schedule_payload) do |*args|
|
1167
|
-
payload = args[0]
|
1168
|
-
end
|
1169
|
-
|
1170
|
-
Rollbar.error(StandardError.new("oops"))
|
1171
|
-
|
1172
|
-
payload["data"][:body][:trace][:frames].should == []
|
1173
|
-
payload["data"][:body][:trace][:exception][:class].should == "StandardError"
|
1174
|
-
payload["data"][:body][:trace][:exception][:message].should == "oops"
|
1175
|
-
end
|
1176
|
-
|
1177
|
-
it 'gets the backtrace from the caller' do
|
1178
|
-
Rollbar.configure do |config|
|
1179
|
-
config.populate_empty_backtraces = true
|
1180
|
-
end
|
1181
|
-
|
1182
|
-
exception = Exception.new
|
1183
|
-
|
1184
|
-
Rollbar.error(exception)
|
1185
|
-
|
1186
|
-
gem_dir = Gem::Specification.find_by_name('rollbar').gem_dir
|
1187
|
-
gem_lib_dir = gem_dir + '/lib'
|
1188
|
-
last_report = Rollbar.last_report
|
1189
|
-
|
1190
|
-
filepaths = last_report[:body][:trace][:frames].map {|frame| frame[:filename] }.reverse
|
1191
|
-
|
1192
|
-
expect(filepaths[0]).not_to include(gem_lib_dir)
|
1193
|
-
expect(filepaths.any? {|filepath| filepath.include?(gem_dir) }).to eq true
|
1194
|
-
end
|
1195
|
-
|
1196
|
-
it 'should return the exception data with a uuid, on platforms with SecureRandom' do
|
1197
|
-
if defined?(SecureRandom) and SecureRandom.respond_to?(:uuid)
|
1198
|
-
exception_data = Rollbar.error(StandardError.new("oops"))
|
1199
|
-
exception_data[:uuid].should_not be_nil
|
1200
|
-
end
|
1201
|
-
end
|
1202
|
-
|
1203
|
-
it 'should report exception objects with nonstandard backtraces' do
|
1204
|
-
payload = nil
|
1205
|
-
|
1206
|
-
notifier.stub(:schedule_payload) do |*args|
|
1207
|
-
payload = args[0]
|
1208
|
-
end
|
1209
|
-
|
1210
|
-
class CustomException < StandardError
|
1211
|
-
def backtrace
|
1212
|
-
["custom backtrace line"]
|
1213
|
-
end
|
1214
|
-
end
|
1215
|
-
|
1216
|
-
exception = CustomException.new("oops")
|
1217
|
-
|
1218
|
-
notifier.error(exception)
|
1219
|
-
|
1220
|
-
payload["data"][:body][:trace][:frames][0][:method].should == "custom backtrace line"
|
1221
|
-
end
|
1222
|
-
|
1223
|
-
it 'should report exceptions with a custom level' do
|
1224
|
-
payload = nil
|
1225
|
-
|
1226
|
-
notifier.stub(:schedule_payload) do |*args|
|
1227
|
-
payload = args[0]
|
1228
|
-
end
|
1229
|
-
|
1230
|
-
Rollbar.error(exception)
|
1231
|
-
|
1232
|
-
payload['data'][:level].should == 'error'
|
1233
|
-
|
1234
|
-
Rollbar.log('debug', exception)
|
1235
|
-
|
1236
|
-
payload['data'][:level].should == 'debug'
|
1237
|
-
end
|
1238
|
-
|
1239
|
-
context 'with invalid utf8 encoding' do
|
1240
|
-
let(:extra) do
|
1241
|
-
{ :extra => force_to_ascii("bad value 1\255") }
|
1242
|
-
end
|
1243
|
-
|
1244
|
-
it 'removes te invalid characteres' do
|
1245
|
-
Rollbar.info('removing invalid chars', extra)
|
1246
|
-
|
1247
|
-
extra_value = Rollbar.last_report[:body][:message][:extra][:extra]
|
1248
|
-
expect(extra_value).to be_eql('bad value 1')
|
1249
|
-
end
|
1250
|
-
end
|
1251
|
-
end
|
1252
|
-
|
1253
|
-
# Backwards
|
1254
|
-
context 'report_message' do
|
1255
|
-
before(:each) do
|
1256
|
-
configure
|
1257
|
-
Rollbar.configure do |config|
|
1258
|
-
config.logger = logger_mock
|
1259
|
-
end
|
1260
|
-
end
|
1261
|
-
|
1262
|
-
let(:logger_mock) { double("Rails.logger").as_null_object }
|
1263
|
-
let(:user) { User.create(:email => 'email@example.com', :encrypted_password => '', :created_at => Time.now, :updated_at => Time.now) }
|
1264
|
-
|
1265
|
-
it 'should report simple messages' do
|
1266
|
-
logger_mock.should_receive(:info).with('[Rollbar] Scheduling payload')
|
1267
|
-
logger_mock.should_receive(:info).with('[Rollbar] Success')
|
1268
|
-
Rollbar.error('Test message')
|
1269
|
-
end
|
1270
|
-
|
1271
|
-
it 'should not report anything when disabled' do
|
1272
|
-
logger_mock.should_not_receive(:info).with('[Rollbar] Success')
|
1273
|
-
Rollbar.configure do |config|
|
1274
|
-
config.enabled = false
|
1275
|
-
end
|
1276
|
-
|
1277
|
-
Rollbar.error('Test message that should be ignored')
|
1278
|
-
|
1279
|
-
Rollbar.configure do |config|
|
1280
|
-
config.enabled = true
|
1281
|
-
end
|
1282
|
-
end
|
1283
|
-
|
1284
|
-
it 'should report messages with extra data' do
|
1285
|
-
logger_mock.should_receive(:info).with('[Rollbar] Success')
|
1286
|
-
Rollbar.debug('Test message with extra data', 'debug', :foo => "bar",
|
1287
|
-
:hash => { :a => 123, :b => "xyz" })
|
1288
|
-
end
|
1289
|
-
|
1290
|
-
# END Backwards
|
1291
|
-
|
1292
|
-
it 'should not crash with circular extra_data' do
|
1293
|
-
a = { :foo => "bar" }
|
1294
|
-
b = { :a => a }
|
1295
|
-
c = { :b => b }
|
1296
|
-
a[:c] = c
|
1297
|
-
|
1298
|
-
logger_mock.should_receive(:error).with(/\[Rollbar\] Reporting internal error encountered while sending data to Rollbar./)
|
1299
|
-
|
1300
|
-
Rollbar.error("Test message with circular extra data", a)
|
1301
|
-
end
|
1302
|
-
|
1303
|
-
it 'should be able to report form validation errors when they are present' do
|
1304
|
-
logger_mock.should_receive(:info).with('[Rollbar] Success')
|
1305
|
-
user.errors.add(:example, "error")
|
1306
|
-
user.report_validation_errors_to_rollbar
|
1307
|
-
end
|
1308
|
-
|
1309
|
-
it 'should not report form validation errors when they are not present' do
|
1310
|
-
logger_mock.should_not_receive(:info).with('[Rollbar] Success')
|
1311
|
-
user.errors.clear
|
1312
|
-
user.report_validation_errors_to_rollbar
|
1313
|
-
end
|
1314
|
-
|
1315
|
-
it 'should report messages with extra data' do
|
1316
|
-
logger_mock.should_receive(:info).with('[Rollbar] Success')
|
1317
|
-
Rollbar.info("Test message with extra data", :foo => "bar",
|
1318
|
-
:hash => { :a => 123, :b => "xyz" })
|
1319
|
-
end
|
1320
|
-
|
1321
|
-
it 'should report messages with request, person data and extra data' do
|
1322
|
-
logger_mock.should_receive(:info).with('[Rollbar] Scheduling payload')
|
1323
|
-
logger_mock.should_receive(:info).with('[Rollbar] Success')
|
1324
|
-
|
1325
|
-
request_data = {
|
1326
|
-
:params => {:foo => 'bar'}
|
1327
|
-
}
|
1328
|
-
|
1329
|
-
person_data = {
|
1330
|
-
:id => 123,
|
1331
|
-
:username => 'username'
|
1332
|
-
}
|
1333
|
-
|
1334
|
-
extra_data = {
|
1335
|
-
:extra_foo => 'extra_bar'
|
1336
|
-
}
|
1337
|
-
|
1338
|
-
Rollbar.configure do |config|
|
1339
|
-
config.payload_options = {
|
1340
|
-
:request => request_data,
|
1341
|
-
:person => person_data
|
1342
|
-
}
|
1343
|
-
end
|
1344
|
-
|
1345
|
-
Rollbar.info("Test message", extra_data)
|
1346
|
-
|
1347
|
-
Rollbar.last_report[:request].should == request_data
|
1348
|
-
Rollbar.last_report[:person].should == person_data
|
1349
|
-
Rollbar.last_report[:body][:message][:extra][:extra_foo].should == 'extra_bar'
|
1350
|
-
end
|
1351
|
-
end
|
1352
|
-
|
1353
|
-
context 'payload_destination' do
|
1354
|
-
before(:each) do
|
1355
|
-
configure
|
1356
|
-
Rollbar.configure do |config|
|
1357
|
-
config.logger = logger_mock
|
1358
|
-
config.filepath = 'test.rollbar'
|
1359
|
-
end
|
1360
|
-
end
|
1361
|
-
|
1362
|
-
after(:each) do
|
1363
|
-
Rollbar.unconfigure
|
1364
|
-
configure
|
1365
|
-
end
|
1366
|
-
|
1367
|
-
let(:exception) do
|
1368
|
-
begin
|
1369
|
-
foo = bar
|
1370
|
-
rescue => e
|
1371
|
-
e
|
1372
|
-
end
|
1373
|
-
end
|
1374
|
-
|
1375
|
-
let(:logger_mock) { double("Rails.logger").as_null_object }
|
1376
|
-
|
1377
|
-
it 'should send the payload over the network by default' do
|
1378
|
-
logger_mock.should_not_receive(:info).with('[Rollbar] Writing payload to file')
|
1379
|
-
logger_mock.should_receive(:info).with('[Rollbar] Sending payload').once
|
1380
|
-
logger_mock.should_receive(:info).with('[Rollbar] Success').once
|
1381
|
-
Rollbar.error(exception)
|
1382
|
-
end
|
1383
|
-
|
1384
|
-
it 'should save the payload to a file if set' do
|
1385
|
-
logger_mock.should_not_receive(:info).with('[Rollbar] Sending payload')
|
1386
|
-
logger_mock.should_receive(:info).with('[Rollbar] Writing payload to file').once
|
1387
|
-
logger_mock.should_receive(:info).with('[Rollbar] Success').once
|
1388
|
-
|
1389
|
-
filepath = ''
|
1390
|
-
|
1391
|
-
Rollbar.configure do |config|
|
1392
|
-
config.write_to_file = true
|
1393
|
-
filepath = config.filepath
|
1394
|
-
end
|
1395
|
-
|
1396
|
-
Rollbar.error(exception)
|
1397
|
-
|
1398
|
-
File.exist?(filepath).should == true
|
1399
|
-
File.read(filepath).should include test_access_token
|
1400
|
-
File.delete(filepath)
|
1401
|
-
|
1402
|
-
Rollbar.configure do |config|
|
1403
|
-
config.write_to_file = false
|
1404
|
-
end
|
1405
|
-
end
|
1406
|
-
end
|
1407
|
-
|
1408
|
-
context 'asynchronous_handling' do
|
1409
|
-
before(:each) do
|
1410
|
-
configure
|
1411
|
-
Rollbar.configure do |config|
|
1412
|
-
config.logger = logger_mock
|
1413
|
-
end
|
1414
|
-
end
|
1415
|
-
|
1416
|
-
after(:each) do
|
1417
|
-
Rollbar.unconfigure
|
1418
|
-
configure
|
1419
|
-
end
|
1420
|
-
|
1421
|
-
let(:exception) do
|
1422
|
-
begin
|
1423
|
-
foo = bar
|
1424
|
-
rescue => e
|
1425
|
-
e
|
1426
|
-
end
|
1427
|
-
end
|
1428
|
-
|
1429
|
-
let(:logger_mock) { double("Rails.logger").as_null_object }
|
1430
|
-
|
1431
|
-
it 'should send the payload using the default asynchronous handler girl_friday' do
|
1432
|
-
logger_mock.should_receive(:info).with('[Rollbar] Scheduling payload')
|
1433
|
-
logger_mock.should_receive(:info).with('[Rollbar] Sending payload')
|
1434
|
-
logger_mock.should_receive(:info).with('[Rollbar] Success')
|
1435
|
-
|
1436
|
-
Rollbar.configure do |config|
|
1437
|
-
config.use_async = true
|
1438
|
-
GirlFriday::WorkQueue.immediate!
|
1439
|
-
end
|
1440
|
-
|
1441
|
-
Rollbar.error(exception)
|
1442
|
-
|
1443
|
-
Rollbar.configure do |config|
|
1444
|
-
config.use_async = false
|
1445
|
-
GirlFriday::WorkQueue.queue!
|
1446
|
-
end
|
1447
|
-
end
|
1448
|
-
|
1449
|
-
it 'should send the payload using a user-supplied asynchronous handler' do
|
1450
|
-
logger_mock.should_receive(:info).with('Custom async handler called')
|
1451
|
-
logger_mock.should_receive(:info).with('[Rollbar] Sending payload')
|
1452
|
-
logger_mock.should_receive(:info).with('[Rollbar] Success')
|
1453
|
-
|
1454
|
-
Rollbar.configure do |config|
|
1455
|
-
config.use_async = true
|
1456
|
-
config.async_handler = Proc.new { |payload|
|
1457
|
-
logger_mock.info 'Custom async handler called'
|
1458
|
-
Rollbar.process_payload(payload)
|
1459
|
-
}
|
1460
|
-
end
|
1461
|
-
|
1462
|
-
Rollbar.error(exception)
|
1463
|
-
end
|
1464
|
-
|
1465
|
-
# We should be able to send String payloads, generated
|
1466
|
-
# by a previous version of the gem. This can happend just
|
1467
|
-
# after a deploy with an gem upgrade.
|
1468
|
-
context 'with a payload generated as String' do
|
1469
|
-
let(:async_handler) do
|
1470
|
-
proc do |payload|
|
1471
|
-
# simulate previous gem version
|
1472
|
-
string_payload = Rollbar::JSON.dump(payload)
|
1473
|
-
|
1474
|
-
Rollbar.process_payload(string_payload)
|
1475
|
-
end
|
1476
|
-
end
|
1477
|
-
|
1478
|
-
before do
|
1479
|
-
Rollbar.configuration.stub(:use_async).and_return(true)
|
1480
|
-
Rollbar.configuration.stub(:async_handler).and_return(async_handler)
|
1481
|
-
end
|
1482
|
-
|
1483
|
-
it 'sends a payload generated as String, not as a Hash' do
|
1484
|
-
logger_mock.should_receive(:info).with('[Rollbar] Success')
|
1485
|
-
|
1486
|
-
Rollbar.error(exception)
|
1487
|
-
end
|
1488
|
-
|
1489
|
-
context 'with async failover handlers' do
|
1490
|
-
before do
|
1491
|
-
Rollbar.reconfigure do |config|
|
1492
|
-
config.use_async = true
|
1493
|
-
config.async_handler = async_handler
|
1494
|
-
config.failover_handlers = handlers
|
1495
|
-
config.logger = logger_mock
|
1496
|
-
end
|
1497
|
-
end
|
1498
|
-
|
1499
|
-
let(:exception) { StandardError.new('the error') }
|
1500
|
-
|
1501
|
-
context 'if the async handler doesnt fail' do
|
1502
|
-
let(:async_handler) { proc { |_| 'success' } }
|
1503
|
-
let(:handler) { proc { |_| 'success' } }
|
1504
|
-
let(:handlers) { [handler] }
|
1505
|
-
|
1506
|
-
it 'doesnt call any failover handler' do
|
1507
|
-
expect(handler).not_to receive(:call)
|
1508
|
-
|
1509
|
-
Rollbar.error(exception)
|
1510
|
-
end
|
1511
|
-
end
|
1512
|
-
|
1513
|
-
context 'if the async handler fails' do
|
1514
|
-
let(:async_handler) { proc { |_| fail 'this handler will crash' } }
|
1515
|
-
|
1516
|
-
context 'if any failover handlers is configured' do
|
1517
|
-
let(:handlers) { [] }
|
1518
|
-
let(:log_message) do
|
1519
|
-
'[Rollbar] Async handler failed, and there are no failover handlers configured. See the docs for "failover_handlers"'
|
1520
|
-
end
|
1521
|
-
|
1522
|
-
it 'logs the error but doesnt try to report an internal error' do
|
1523
|
-
expect(logger_mock).to receive(:error).with(log_message)
|
1524
|
-
|
1525
|
-
Rollbar.error(exception)
|
1526
|
-
end
|
1527
|
-
end
|
1528
|
-
|
1529
|
-
context 'if the first failover handler success' do
|
1530
|
-
let(:handler) { proc { |_| 'success' } }
|
1531
|
-
let(:handlers) { [handler] }
|
1532
|
-
|
1533
|
-
it 'calls the failover handler and doesnt report internal error' do
|
1534
|
-
expect(Rollbar).not_to receive(:report_internal_error)
|
1535
|
-
expect(handler).to receive(:call)
|
1536
|
-
|
1537
|
-
Rollbar.error(exception)
|
1538
|
-
end
|
1539
|
-
end
|
1540
|
-
|
1541
|
-
context 'with two handlers, the first failing' do
|
1542
|
-
let(:handler1) { proc { |_| fail 'this handler fails' } }
|
1543
|
-
let(:handler2) { proc { |_| 'success' } }
|
1544
|
-
let(:handlers) { [handler1, handler2] }
|
1545
|
-
|
1546
|
-
it 'calls the second handler and doesnt report internal error' do
|
1547
|
-
expect(handler2).to receive(:call)
|
1548
|
-
|
1549
|
-
Rollbar.error(exception)
|
1550
|
-
end
|
1551
|
-
end
|
1552
|
-
|
1553
|
-
context 'with two handlers, both failing' do
|
1554
|
-
let(:handler1) { proc { |_| fail 'this handler fails' } }
|
1555
|
-
let(:handler2) { proc { |_| fail 'this will also fail' } }
|
1556
|
-
let(:handlers) { [handler1, handler2] }
|
1557
|
-
|
1558
|
-
it 'reports internal error' do
|
1559
|
-
expect(logger_mock).to receive(:error)
|
1560
|
-
|
1561
|
-
Rollbar.error(exception)
|
1562
|
-
end
|
1563
|
-
end
|
1564
|
-
end
|
1565
|
-
end
|
1566
|
-
end
|
1567
|
-
|
1568
|
-
describe "#use_sucker_punch", :if => defined?(SuckerPunch) do
|
1569
|
-
it "should send the payload to sucker_punch delayer" do
|
1570
|
-
logger_mock.should_receive(:info).with('[Rollbar] Scheduling payload')
|
1571
|
-
logger_mock.should_receive(:info).with('[Rollbar] Sending payload')
|
1572
|
-
logger_mock.should_receive(:info).with('[Rollbar] Success')
|
1573
|
-
|
1574
|
-
Rollbar.configure do |config|
|
1575
|
-
config.use_sucker_punch
|
1576
|
-
end
|
1577
|
-
|
1578
|
-
Rollbar.error(exception)
|
1579
|
-
end
|
1580
|
-
end
|
1581
|
-
|
1582
|
-
describe "#use_sidekiq", :if => defined?(Sidekiq) do
|
1583
|
-
it "should instanciate sidekiq delayer with custom values" do
|
1584
|
-
Rollbar::Delay::Sidekiq.should_receive(:new).with('queue' => 'test_queue')
|
1585
|
-
config = Rollbar::Configuration.new
|
1586
|
-
config.use_sidekiq 'queue' => 'test_queue'
|
1587
|
-
end
|
1588
|
-
|
1589
|
-
it "should send the payload to sidekiq delayer" do
|
1590
|
-
handler = double('sidekiq_handler_mock')
|
1591
|
-
handler.should_receive(:call)
|
1592
|
-
|
1593
|
-
Rollbar.configure do |config|
|
1594
|
-
config.use_sidekiq
|
1595
|
-
config.async_handler = handler
|
1596
|
-
end
|
1597
|
-
|
1598
|
-
Rollbar.error(exception)
|
1599
|
-
end
|
1600
|
-
end
|
1601
|
-
end
|
1602
|
-
|
1603
|
-
context 'logger' do
|
1604
|
-
before(:each) do
|
1605
|
-
reset_configuration
|
1606
|
-
end
|
1607
|
-
|
1608
|
-
it 'should have use the Rails logger when configured to do so' do
|
1609
|
-
configure
|
1610
|
-
expect(Rollbar.send(:logger)).to be_kind_of(Rollbar::LoggerProxy)
|
1611
|
-
expect(Rollbar.send(:logger).object).to eq ::Rails.logger
|
1612
|
-
end
|
1613
|
-
|
1614
|
-
it 'should use the default_logger when no logger is set' do
|
1615
|
-
logger = Logger.new(STDERR)
|
1616
|
-
|
1617
|
-
Rollbar.configure do |config|
|
1618
|
-
config.default_logger = lambda { logger }
|
1619
|
-
end
|
1620
|
-
|
1621
|
-
Rollbar.send(:logger).object.should == logger
|
1622
|
-
end
|
1623
|
-
|
1624
|
-
it 'should have a default default_logger' do
|
1625
|
-
Rollbar.send(:logger).should_not be_nil
|
1626
|
-
end
|
1627
|
-
|
1628
|
-
after(:each) do
|
1629
|
-
reset_configuration
|
1630
|
-
end
|
1631
|
-
end
|
1632
|
-
|
1633
|
-
context 'enforce_valid_utf8' do
|
1634
|
-
# TODO(jon): all these tests should be removed since they are in
|
1635
|
-
# in spec/rollbar/encoding/encoder.rb.
|
1636
|
-
#
|
1637
|
-
# This should just check that in payload with simple values and
|
1638
|
-
# nested values are each one passed through Rollbar::Encoding.encode
|
1639
|
-
context 'with utf8 string and ruby > 1.8' do
|
1640
|
-
next unless String.instance_methods.include?(:force_encoding)
|
1641
|
-
|
1642
|
-
let(:payload) { { :foo => 'Изменение' } }
|
1643
|
-
|
1644
|
-
it 'just returns the same string' do
|
1645
|
-
payload_copy = payload.clone
|
1646
|
-
notifier.send(:enforce_valid_utf8, payload_copy)
|
1647
|
-
|
1648
|
-
expect(payload_copy[:foo]).to be_eql('Изменение')
|
1649
|
-
end
|
1650
|
-
end
|
1651
|
-
|
1652
|
-
it 'should replace invalid utf8 values' do
|
1653
|
-
bad_key = force_to_ascii("inner \x92bad key")
|
1654
|
-
|
1655
|
-
payload = {
|
1656
|
-
:bad_value => force_to_ascii("bad value 1\255"),
|
1657
|
-
:bad_value_2 => force_to_ascii("bad\255 value 2"),
|
1658
|
-
force_to_ascii("bad\255 key") => "good value",
|
1659
|
-
:hash => {
|
1660
|
-
:inner_bad_value => force_to_ascii("\255\255bad value 3"),
|
1661
|
-
bad_key.to_sym => 'inner good value',
|
1662
|
-
force_to_ascii("bad array key\255") => [
|
1663
|
-
'good array value 1',
|
1664
|
-
force_to_ascii("bad\255 array value 1\255"),
|
1665
|
-
{
|
1666
|
-
:inner_inner_bad => force_to_ascii("bad inner \255inner value")
|
1667
|
-
}
|
1668
|
-
]
|
1669
|
-
}
|
1670
|
-
}
|
1671
|
-
|
1672
|
-
|
1673
|
-
payload_copy = payload.clone
|
1674
|
-
notifier.send(:enforce_valid_utf8, payload_copy)
|
1675
|
-
|
1676
|
-
payload_copy[:bad_value].should == "bad value 1"
|
1677
|
-
payload_copy[:bad_value_2].should == "bad value 2"
|
1678
|
-
payload_copy["bad key"].should == "good value"
|
1679
|
-
payload_copy.keys.should_not include("bad\456 key")
|
1680
|
-
payload_copy[:hash][:inner_bad_value].should == "bad value 3"
|
1681
|
-
payload_copy[:hash][:"inner bad key"].should == 'inner good value'
|
1682
|
-
payload_copy[:hash]["bad array key"].should == [
|
1683
|
-
'good array value 1',
|
1684
|
-
'bad array value 1',
|
1685
|
-
{
|
1686
|
-
:inner_inner_bad => 'bad inner inner value'
|
1687
|
-
}
|
1688
|
-
]
|
1689
|
-
end
|
1690
|
-
end
|
1691
|
-
|
1692
|
-
context 'truncate_payload' do
|
1693
|
-
it 'should truncate all nested strings in the payload' do
|
1694
|
-
payload = {
|
1695
|
-
:truncated => '1234567',
|
1696
|
-
:not_truncated => '123456',
|
1697
|
-
:hash => {
|
1698
|
-
:inner_truncated => '123456789',
|
1699
|
-
:inner_not_truncated => '567',
|
1700
|
-
:array => ['12345678', '12', {:inner_inner => '123456789'}]
|
1701
|
-
}
|
1702
|
-
}
|
1703
|
-
|
1704
|
-
payload_copy = payload.clone
|
1705
|
-
notifier.send(:truncate_payload, payload_copy, 6)
|
1706
|
-
|
1707
|
-
payload_copy[:truncated].should == '123...'
|
1708
|
-
payload_copy[:not_truncated].should == '123456'
|
1709
|
-
payload_copy[:hash][:inner_truncated].should == '123...'
|
1710
|
-
payload_copy[:hash][:inner_not_truncated].should == '567'
|
1711
|
-
payload_copy[:hash][:array].should == ['123...', '12', {:inner_inner => '123...'}]
|
1712
|
-
end
|
1713
|
-
|
1714
|
-
it 'should truncate utf8 strings properly' do
|
1715
|
-
payload = {
|
1716
|
-
:truncated => 'Ŝǻмρļẻ śţяịņģ',
|
1717
|
-
:not_truncated => '123456',
|
1718
|
-
}
|
1719
|
-
|
1720
|
-
payload_copy = payload.clone
|
1721
|
-
notifier.send(:truncate_payload, payload_copy, 6)
|
1722
|
-
|
1723
|
-
payload_copy[:truncated].should == "Ŝǻм..."
|
1724
|
-
payload_copy[:not_truncated].should == '123456'
|
1725
|
-
end
|
1726
|
-
end
|
1727
|
-
|
1728
|
-
context 'server_data' do
|
1729
|
-
it 'should have the right hostname' do
|
1730
|
-
notifier.send(:server_data)[:host] == Socket.gethostname
|
1731
|
-
end
|
1732
|
-
|
1733
|
-
it 'should have root and branch set when configured' do
|
1734
|
-
configure
|
1735
|
-
Rollbar.configure do |config|
|
1736
|
-
config.root = '/path/to/root'
|
1737
|
-
config.branch = 'master'
|
1738
|
-
end
|
1739
|
-
|
1740
|
-
data = notifier.send(:server_data)
|
1741
|
-
data[:root].should == '/path/to/root'
|
1742
|
-
data[:branch].should == 'master'
|
1743
|
-
end
|
1744
|
-
end
|
1745
|
-
|
1746
|
-
context "project_gems" do
|
1747
|
-
it "should include gem paths for specified project gems in the payload" do
|
1748
|
-
gems = ['rack', 'rspec-rails']
|
1749
|
-
gem_paths = []
|
1750
|
-
|
1751
|
-
Rollbar.configure do |config|
|
1752
|
-
config.project_gems = gems
|
1753
|
-
end
|
1754
|
-
|
1755
|
-
gems.each {|gem|
|
1756
|
-
gem_paths.push(Gem::Specification.find_by_name(gem).gem_dir)
|
1757
|
-
}
|
1758
|
-
|
1759
|
-
data = notifier.send(:build_payload, 'info', 'test', nil, {})['data']
|
1760
|
-
data[:project_package_paths].kind_of?(Array).should == true
|
1761
|
-
data[:project_package_paths].length.should == gem_paths.length
|
1762
|
-
|
1763
|
-
data[:project_package_paths].each_with_index{|path, index|
|
1764
|
-
path.should == gem_paths[index]
|
1765
|
-
}
|
1766
|
-
end
|
1767
|
-
|
1768
|
-
it "should handle regex gem patterns" do
|
1769
|
-
gems = ["rack", /rspec/, /roll/]
|
1770
|
-
gem_paths = []
|
1771
|
-
|
1772
|
-
Rollbar.configure do |config|
|
1773
|
-
config.project_gems = gems
|
1774
|
-
end
|
1775
|
-
|
1776
|
-
gem_paths = gems.map{|gem| Gem::Specification.find_all_by_name(gem).map(&:gem_dir) }.flatten.compact.uniq
|
1777
|
-
gem_paths.length.should > 1
|
1778
|
-
|
1779
|
-
gem_paths.any?{|path| path.include? 'rollbar-gem'}.should == true
|
1780
|
-
gem_paths.any?{|path| path.include? 'rspec-rails'}.should == true
|
1781
|
-
|
1782
|
-
data = notifier.send(:build_payload, 'info', 'test', nil, {})['data']
|
1783
|
-
data[:project_package_paths].kind_of?(Array).should == true
|
1784
|
-
data[:project_package_paths].length.should == gem_paths.length
|
1785
|
-
(data[:project_package_paths] - gem_paths).length.should == 0
|
1786
|
-
end
|
1787
|
-
|
1788
|
-
it "should not break on non-existent gems" do
|
1789
|
-
gems = ["this_gem_does_not_exist", "rack"]
|
1790
|
-
|
1791
|
-
Rollbar.configure do |config|
|
1792
|
-
config.project_gems = gems
|
1793
|
-
end
|
1794
|
-
|
1795
|
-
data = notifier.send(:build_payload, 'info', 'test', nil, {})['data']
|
1796
|
-
data[:project_package_paths].kind_of?(Array).should == true
|
1797
|
-
data[:project_package_paths].length.should == 1
|
1798
|
-
end
|
1799
|
-
end
|
1800
|
-
|
1801
|
-
context 'report_internal_error', :reconfigure_notifier => true do
|
1802
|
-
it "should not crash when given an exception object" do
|
1803
|
-
begin
|
1804
|
-
1 / 0
|
1805
|
-
rescue => e
|
1806
|
-
notifier.send(:report_internal_error, e)
|
1807
|
-
end
|
1808
|
-
end
|
1809
|
-
end
|
1810
|
-
|
1811
|
-
context "send_failsafe" do
|
1812
|
-
let(:exception) { StandardError.new }
|
1813
|
-
|
1814
|
-
it "doesn't crash when given a message and exception" do
|
1815
|
-
sent_payload = notifier.send(:send_failsafe, "test failsafe", exception)
|
1816
|
-
|
1817
|
-
expected_message = 'Failsafe from rollbar-gem. StandardError: test failsafe'
|
1818
|
-
expect(sent_payload['data'][:body][:message][:body]).to be_eql(expected_message)
|
1819
|
-
end
|
1820
|
-
|
1821
|
-
it "doesn't crash when given all nils" do
|
1822
|
-
notifier.send(:send_failsafe, nil, nil)
|
1823
|
-
end
|
1824
|
-
|
1825
|
-
context 'with a non default exception message' do
|
1826
|
-
let(:exception) { StandardError.new 'Something is wrong' }
|
1827
|
-
|
1828
|
-
it 'adds it to exception info' do
|
1829
|
-
sent_payload = notifier.send(:send_failsafe, "test failsafe", exception)
|
1830
|
-
|
1831
|
-
expected_message = 'Failsafe from rollbar-gem. StandardError: "Something is wrong": test failsafe'
|
1832
|
-
expect(sent_payload['data'][:body][:message][:body]).to be_eql(expected_message)
|
1833
|
-
end
|
1834
|
-
end
|
1835
|
-
|
1836
|
-
context 'without exception object' do
|
1837
|
-
it 'just sends the given message' do
|
1838
|
-
sent_payload = notifier.send(:send_failsafe, "test failsafe", nil)
|
1839
|
-
|
1840
|
-
expected_message = 'Failsafe from rollbar-gem. test failsafe'
|
1841
|
-
expect(sent_payload['data'][:body][:message][:body]).to be_eql(expected_message)
|
1842
|
-
end
|
1843
|
-
end
|
1844
|
-
|
1845
|
-
context 'if the exception has a backtrace' do
|
1846
|
-
let(:backtrace) { ['func3', 'func2', 'func1'] }
|
1847
|
-
let(:failsafe_reason) { 'StandardError in func3: test failsafe' }
|
1848
|
-
let(:expected_body) { "Failsafe from rollbar-gem. #{failsafe_reason}" }
|
1849
|
-
let(:expected_log_message) do
|
1850
|
-
"[Rollbar] Sending failsafe response due to #{failsafe_reason}"
|
1851
|
-
end
|
1852
|
-
|
1853
|
-
before { exception.set_backtrace(backtrace) }
|
1854
|
-
|
1855
|
-
it 'adds the nearest frame to the message' do
|
1856
|
-
expect(notifier).to receive(:log_error).with(expected_log_message)
|
1857
|
-
|
1858
|
-
sent_payload = notifier.send(:send_failsafe, "test failsafe", exception)
|
1859
|
-
|
1860
|
-
expect(sent_payload['data'][:body][:message][:body]).to be_eql(expected_body)
|
1861
|
-
end
|
1862
|
-
end
|
1863
|
-
end
|
1864
|
-
|
1865
|
-
context 'when reporting internal error with nil context' do
|
1866
|
-
let(:context_proc) { proc {} }
|
1867
|
-
let(:scoped_notifier) { notifier.scope(:context => context_proc) }
|
1868
|
-
let(:exception) { Exception.new }
|
1869
|
-
let(:logger_mock) { double("Rails.logger").as_null_object }
|
1870
|
-
|
1871
|
-
it 'reports successfully' do
|
1872
|
-
configure
|
1873
|
-
|
1874
|
-
Rollbar.configure do |config|
|
1875
|
-
config.logger = logger_mock
|
1876
|
-
end
|
1877
|
-
|
1878
|
-
logger_mock.should_receive(:info).with('[Rollbar] Sending payload').once
|
1879
|
-
logger_mock.should_receive(:info).with('[Rollbar] Success').once
|
1880
|
-
scoped_notifier.send(:report_internal_error, exception)
|
1881
|
-
end
|
1882
|
-
end
|
1883
|
-
|
1884
|
-
context "request_data_extractor" do
|
1885
|
-
before(:each) do
|
1886
|
-
class DummyClass
|
1887
|
-
end
|
1888
|
-
@dummy_class = DummyClass.new
|
1889
|
-
@dummy_class.extend(Rollbar::RequestDataExtractor)
|
1890
|
-
end
|
1891
|
-
|
1892
|
-
context "rollbar_headers" do
|
1893
|
-
it "should not include cookies" do
|
1894
|
-
env = {"HTTP_USER_AGENT" => "test", "HTTP_COOKIE" => "cookie"}
|
1895
|
-
headers = @dummy_class.send(:rollbar_headers, env)
|
1896
|
-
headers.should have_key "User-Agent"
|
1897
|
-
headers.should_not have_key "Cookie"
|
1898
|
-
end
|
1899
|
-
end
|
1900
|
-
end
|
1901
|
-
|
1902
|
-
describe '.scoped' do
|
1903
|
-
let(:scope_options) do
|
1904
|
-
{ :foo => 'bar' }
|
1905
|
-
end
|
1906
|
-
|
1907
|
-
it 'changes data in scope_object inside the block' do
|
1908
|
-
Rollbar.reset_notifier!
|
1909
|
-
configure
|
1910
|
-
|
1911
|
-
current_notifier_id = Rollbar.notifier.object_id
|
1912
|
-
|
1913
|
-
Rollbar.scoped(scope_options) do
|
1914
|
-
scope_object = Rollbar.notifier.scope_object
|
1915
|
-
|
1916
|
-
expect(Rollbar.notifier.object_id).not_to be_eql(current_notifier_id)
|
1917
|
-
expect(scope_object).to be_eql(scope_options)
|
1918
|
-
end
|
1919
|
-
|
1920
|
-
expect(Rollbar.notifier.object_id).to be_eql(current_notifier_id)
|
1921
|
-
end
|
1922
|
-
|
1923
|
-
context 'if the block fails' do
|
1924
|
-
let(:crashing_block) { proc { fail } }
|
1925
|
-
|
1926
|
-
it 'restores the old notifier' do
|
1927
|
-
notifier = Rollbar.notifier
|
1928
|
-
|
1929
|
-
expect { Rollbar.scoped(&crashing_block) }.to raise_error
|
1930
|
-
expect(notifier).to be_eql(Rollbar.notifier)
|
1931
|
-
end
|
1932
|
-
end
|
1933
|
-
|
1934
|
-
context 'if the block creates a new thread' do
|
1935
|
-
let(:block) do
|
1936
|
-
proc do
|
1937
|
-
Thread.new do
|
1938
|
-
scope = Rollbar.notifier.scope_object
|
1939
|
-
Thread.main[:inner_scope] = scope
|
1940
|
-
end.join
|
1941
|
-
end
|
1942
|
-
end
|
1943
|
-
|
1944
|
-
let(:scope) do
|
1945
|
-
{ :foo => 'bar' }
|
1946
|
-
end
|
1947
|
-
|
1948
|
-
it 'maintains the parent thread notifier scope' do
|
1949
|
-
Rollbar.scoped(scope, &block)
|
1950
|
-
|
1951
|
-
expect(Thread.main[:inner_scope]).to be_eql(scope)
|
1952
|
-
end
|
1953
|
-
end
|
1954
|
-
end
|
1955
|
-
|
1956
|
-
describe '.scope!' do
|
1957
|
-
let(:new_scope) do
|
1958
|
-
{ :person => { :id => 1 } }
|
1959
|
-
end
|
1960
|
-
|
1961
|
-
before { reconfigure_notifier }
|
1962
|
-
|
1963
|
-
it 'adds the new scope to the payload options' do
|
1964
|
-
scope_object = Rollbar.notifier.scope_object
|
1965
|
-
Rollbar.scope!(new_scope)
|
1966
|
-
|
1967
|
-
expect(scope_object).to be_eql(new_scope)
|
1968
|
-
end
|
1969
|
-
end
|
1970
|
-
|
1971
|
-
describe '.reset_notifier' do
|
1972
|
-
it 'resets the notifier' do
|
1973
|
-
notifier1_id = Rollbar.notifier.object_id
|
1974
|
-
|
1975
|
-
Rollbar.reset_notifier!
|
1976
|
-
expect(Rollbar.notifier.object_id).not_to be_eql(notifier1_id)
|
1977
|
-
end
|
1978
|
-
end
|
1979
|
-
|
1980
|
-
describe '.process_payload' do
|
1981
|
-
context 'if there is an exception sending the payload' do
|
1982
|
-
let(:exception) { StandardError.new('error message') }
|
1983
|
-
let(:payload) { { :foo => :bar } }
|
1984
|
-
|
1985
|
-
it 'logs the error and the payload' do
|
1986
|
-
allow(Rollbar.notifier).to receive(:send_payload).and_raise(exception)
|
1987
|
-
expect(Rollbar.notifier).to receive(:log_error)
|
1988
|
-
|
1989
|
-
expect { Rollbar.notifier.process_payload(payload) }.to raise_error(exception)
|
1990
|
-
end
|
1991
|
-
end
|
1992
|
-
end
|
1993
|
-
|
1994
|
-
describe '.process_from_async_handler' do
|
1995
|
-
context 'with errors' do
|
1996
|
-
let(:exception) { StandardError.new('the error') }
|
1997
|
-
|
1998
|
-
it 'raises anything and sends internal error' do
|
1999
|
-
allow(Rollbar.notifier).to receive(:process_payload).and_raise(exception)
|
2000
|
-
expect(Rollbar.notifier).to receive(:report_internal_error).with(exception)
|
2001
|
-
|
2002
|
-
expect do
|
2003
|
-
Rollbar.notifier.process_from_async_handler({})
|
2004
|
-
end.to raise_error(exception)
|
2005
|
-
|
2006
|
-
rollbar_do_not_report = exception.instance_variable_get(:@_rollbar_do_not_report)
|
2007
|
-
expect(rollbar_do_not_report).to be_eql(true)
|
2008
|
-
end
|
2009
|
-
end
|
2010
|
-
end
|
2011
|
-
|
2012
|
-
describe '#custom_data' do
|
2013
|
-
before do
|
2014
|
-
Rollbar.configure do |config|
|
2015
|
-
config.custom_data_method = proc { raise 'this-will-raise' }
|
2016
|
-
end
|
2017
|
-
|
2018
|
-
expect_any_instance_of(Rollbar::Notifier).to receive(:error).and_return(report_data)
|
2019
|
-
end
|
2020
|
-
|
2021
|
-
context 'with uuid in reported data' do
|
2022
|
-
next unless defined?(SecureRandom) and SecureRandom.respond_to?(:uuid)
|
2023
|
-
|
2024
|
-
let(:report_data) { { :uuid => SecureRandom.uuid } }
|
2025
|
-
let(:expected_url) { "https://rollbar.com/instance/uuid?uuid=#{report_data[:uuid]}" }
|
2026
|
-
|
2027
|
-
it 'returns the uuid in :_error_in_custom_data_method' do
|
2028
|
-
expect(notifier.custom_data).to be_eql(:_error_in_custom_data_method => expected_url)
|
2029
|
-
end
|
2030
|
-
end
|
2031
|
-
|
2032
|
-
context 'without uuid in reported data' do
|
2033
|
-
let(:report_data) { { :some => 'other-data' } }
|
2034
|
-
|
2035
|
-
it 'returns the uuid in :_error_in_custom_data_method' do
|
2036
|
-
expect(notifier.custom_data).to be_eql({})
|
2037
|
-
end
|
2038
|
-
end
|
2039
|
-
end
|
2040
|
-
|
2041
|
-
describe '.preconfigure'do
|
2042
|
-
before do
|
2043
|
-
Rollbar.unconfigure
|
2044
|
-
Rollbar.reset_notifier!
|
2045
|
-
end
|
2046
|
-
|
2047
|
-
it 'resets the notifier' do
|
2048
|
-
Rollbar.configure do |config|
|
2049
|
-
config.access_token = 'foo'
|
2050
|
-
end
|
2051
|
-
|
2052
|
-
Thread.new {}
|
2053
|
-
|
2054
|
-
Rollbar.preconfigure do |config|
|
2055
|
-
config.root = 'bar'
|
2056
|
-
end
|
2057
|
-
|
2058
|
-
notifier_config = Rollbar.notifier.configuration
|
2059
|
-
expect(notifier_config.root).to be_eql('bar')
|
2060
|
-
end
|
2061
|
-
end
|
2062
|
-
|
2063
|
-
# configure with some basic params
|
2064
|
-
def configure
|
2065
|
-
reconfigure_notifier
|
2066
|
-
end
|
2067
|
-
end
|