exception_handling 2.17.0.pre.tstarck.1 → 3.0.pre.1
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/.gitignore +0 -3
- data/.ruby-version +1 -1
- data/Gemfile +16 -12
- data/Gemfile.lock +138 -153
- data/README.md +21 -90
- data/Rakefile +11 -8
- data/exception_handling.gemspec +10 -14
- data/lib/exception_handling/exception_info.rb +11 -15
- data/lib/exception_handling/honeybadger_callbacks.rb +59 -0
- data/lib/exception_handling/log_stub_error.rb +1 -2
- data/lib/exception_handling/methods.rb +53 -6
- data/lib/exception_handling/testing.rb +10 -20
- data/lib/exception_handling/version.rb +1 -1
- data/lib/exception_handling.rb +34 -135
- data/semaphore_ci/setup.sh +3 -0
- data/{spec → test}/helpers/exception_helpers.rb +2 -2
- data/{spec/spec_helper.rb → test/test_helper.rb} +45 -75
- data/test/unit/exception_handling/exception_catalog_test.rb +85 -0
- data/test/unit/exception_handling/exception_description_test.rb +82 -0
- data/{spec/unit/exception_handling/exception_info_spec.rb → test/unit/exception_handling/exception_info_test.rb} +114 -170
- data/test/unit/exception_handling/honeybadger_callbacks_test.rb +122 -0
- data/{spec/unit/exception_handling/log_error_stub_spec.rb → test/unit/exception_handling/log_error_stub_test.rb} +22 -38
- data/{spec/unit/exception_handling/mailer_spec.rb → test/unit/exception_handling/mailer_test.rb} +18 -17
- data/test/unit/exception_handling/methods_test.rb +84 -0
- data/test/unit/exception_handling/sensu_test.rb +52 -0
- data/test/unit/exception_handling_test.rb +1109 -0
- metadata +59 -99
- data/.github/CODEOWNERS +0 -1
- data/.github/workflows/pipeline.yml +0 -36
- data/.rspec +0 -3
- data/.tool-versions +0 -1
- data/Appraisals +0 -19
- data/CHANGELOG.md +0 -149
- data/gemfiles/rails_5.gemfile +0 -18
- data/gemfiles/rails_6.gemfile +0 -18
- data/gemfiles/rails_7.gemfile +0 -18
- data/lib/exception_handling/escalate_callback.rb +0 -19
- data/lib/exception_handling/logging_methods.rb +0 -27
- data/spec/rake_test_warning_false.rb +0 -20
- data/spec/unit/exception_handling/escalate_callback_spec.rb +0 -81
- data/spec/unit/exception_handling/exception_catalog_spec.rb +0 -85
- data/spec/unit/exception_handling/exception_description_spec.rb +0 -82
- data/spec/unit/exception_handling/logging_methods_spec.rb +0 -38
- data/spec/unit/exception_handling/methods_spec.rb +0 -105
- data/spec/unit/exception_handling/sensu_spec.rb +0 -51
- data/spec/unit/exception_handling_spec.rb +0 -1465
- /data/{spec → test}/helpers/controller_helpers.rb +0 -0
@@ -1,75 +1,58 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require File.expand_path('../../
|
3
|
+
require File.expand_path('../../test_helper', __dir__)
|
4
4
|
require_test_helper 'controller_helpers'
|
5
5
|
require_test_helper 'exception_helpers'
|
6
6
|
|
7
7
|
module ExceptionHandling
|
8
|
-
|
8
|
+
class ExceptionInfoTest < ActiveSupport::TestCase
|
9
9
|
include ControllerHelpers
|
10
10
|
include ExceptionHelpers
|
11
11
|
|
12
12
|
context "initialize" do
|
13
|
-
|
13
|
+
setup do
|
14
14
|
@exception = StandardError.new("something went wrong")
|
15
15
|
@timestamp = Time.now
|
16
16
|
@controller = Object.new
|
17
17
|
end
|
18
18
|
|
19
19
|
context "controller_from_context" do
|
20
|
-
|
20
|
+
should "extract controller from context when not specified explicitly" do
|
21
21
|
exception_context = {
|
22
22
|
"action_controller.instance" => @controller
|
23
23
|
}
|
24
24
|
exception_info = ExceptionInfo.new(@exception, exception_context, @timestamp)
|
25
|
-
|
25
|
+
assert_equal @controller, exception_info.controller
|
26
26
|
end
|
27
27
|
|
28
|
-
|
28
|
+
should "prefer the explicit controller over the one from context" do
|
29
29
|
exception_context = {
|
30
30
|
"action_controller.instance" => Object.new
|
31
31
|
}
|
32
|
-
exception_info = ExceptionInfo.new(@exception, exception_context, @timestamp,
|
33
|
-
|
34
|
-
|
32
|
+
exception_info = ExceptionInfo.new(@exception, exception_context, @timestamp, @controller)
|
33
|
+
assert_equal @controller, exception_info.controller
|
34
|
+
assert_not_equal exception_context["action_controller.instance"], exception_info.controller
|
35
35
|
end
|
36
36
|
|
37
|
-
|
37
|
+
should "leave controller unset when not included in the context hash" do
|
38
38
|
exception_info = ExceptionInfo.new(@exception, {}, @timestamp)
|
39
|
-
|
39
|
+
assert_nil exception_info.controller
|
40
40
|
end
|
41
41
|
|
42
|
-
|
42
|
+
should "leave controller unset when context is not in hash format" do
|
43
43
|
exception_info = ExceptionInfo.new(@exception, "string context", @timestamp)
|
44
|
-
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
context "honeybadger_tags" do
|
49
|
-
it "retrieved from log_context" do
|
50
|
-
exception_info = ExceptionInfo.new(@exception, "string context", @timestamp, log_context: { honeybadger_tags: ['Data-Services'] })
|
51
|
-
expect(exception_info.honeybadger_tags).to eq(['Data-Services'])
|
52
|
-
end
|
53
|
-
|
54
|
-
it "retrieved from log_context and normalized to array if a string" do
|
55
|
-
exception_info = ExceptionInfo.new(@exception, "string context", @timestamp, log_context: { honeybadger_tags: 'Data-Services' })
|
56
|
-
expect(exception_info.honeybadger_tags).to eq(['Data-Services'])
|
57
|
-
end
|
58
|
-
|
59
|
-
it "defaults to empty array if not given" do
|
60
|
-
exception_info = ExceptionInfo.new(@exception, "string context", @timestamp)
|
61
|
-
expect(exception_info.honeybadger_tags).to eq([])
|
44
|
+
assert_nil exception_info.controller
|
62
45
|
end
|
63
46
|
end
|
64
47
|
end
|
65
48
|
|
66
49
|
context "data" do
|
67
|
-
|
50
|
+
setup do
|
68
51
|
@exception = StandardError.new("something went wrong")
|
69
52
|
@timestamp = Time.now
|
70
53
|
end
|
71
54
|
|
72
|
-
|
55
|
+
should "return a hash with exception specific data including context hash" do
|
73
56
|
exception_context = {
|
74
57
|
"rack.session" => {
|
75
58
|
user_id: 23,
|
@@ -90,17 +73,17 @@ module ExceptionHandling
|
|
90
73
|
}
|
91
74
|
}
|
92
75
|
|
93
|
-
|
76
|
+
assert_equal_with_diff expected_data, exception_info.data
|
94
77
|
end
|
95
78
|
|
96
|
-
|
79
|
+
should "generate exception data appropriately if exception message is nil" do
|
97
80
|
exception_info = ExceptionInfo.new(exception_with_nil_message, "custom context data", @timestamp)
|
98
81
|
exception_data = exception_info.data
|
99
|
-
|
100
|
-
|
82
|
+
assert_equal "RuntimeError: ", exception_data["error_string"]
|
83
|
+
assert_equal "RuntimeError: : custom context data", exception_data["error"]
|
101
84
|
end
|
102
85
|
|
103
|
-
|
86
|
+
should "return a hash with exception specific data including context string" do
|
104
87
|
exception_context = "custom context data"
|
105
88
|
exception_info = ExceptionInfo.new(@exception, exception_context, @timestamp)
|
106
89
|
expected_data = {
|
@@ -113,20 +96,21 @@ module ExceptionHandling
|
|
113
96
|
"message" => "custom context data"
|
114
97
|
}
|
115
98
|
}
|
116
|
-
|
99
|
+
|
100
|
+
assert_equal_with_diff expected_data, exception_info.data
|
117
101
|
end
|
118
102
|
|
119
|
-
|
103
|
+
should "not include enhanced data from controller or custom data callback" do
|
120
104
|
env = { server: "fe98" }
|
121
105
|
parameters = { advertiser_id: 435 }
|
122
106
|
session = { username: "jsmith" }
|
123
107
|
request_uri = "host/path"
|
124
108
|
controller = create_dummy_controller(env, parameters, session, request_uri)
|
125
109
|
data_callback = ->(data) { data[:custom_section] = "value" }
|
126
|
-
exception_info = ExceptionInfo.new(@exception, "custom context data", @timestamp, controller
|
110
|
+
exception_info = ExceptionInfo.new(@exception, "custom context data", @timestamp, controller, data_callback)
|
127
111
|
|
128
|
-
|
129
|
-
|
112
|
+
dont_allow(exception_info).extract_and_merge_controller_data
|
113
|
+
dont_allow(exception_info).customize_from_data_callback
|
130
114
|
expected_data = {
|
131
115
|
"error_class" => "StandardError",
|
132
116
|
"error_string" => "StandardError: something went wrong",
|
@@ -138,12 +122,12 @@ module ExceptionHandling
|
|
138
122
|
}
|
139
123
|
}
|
140
124
|
|
141
|
-
|
125
|
+
assert_equal_with_diff expected_data, exception_info.data
|
142
126
|
end
|
143
127
|
end
|
144
128
|
|
145
129
|
context "enhanced_data" do
|
146
|
-
|
130
|
+
setup do
|
147
131
|
@exception = StandardError.new("something went wrong")
|
148
132
|
@timestamp = Time.now
|
149
133
|
@exception_context = {
|
@@ -161,13 +145,13 @@ module ExceptionHandling
|
|
161
145
|
@data_callback = ->(data) { data[:custom_section] = "check this out" }
|
162
146
|
end
|
163
147
|
|
164
|
-
|
148
|
+
should "not return a mutable object for the session" do
|
165
149
|
exception_info = ExceptionInfo.new(@exception, @exception_context, @timestamp)
|
166
150
|
exception_info.enhanced_data["session"]["hello"] = "world"
|
167
|
-
|
151
|
+
assert_nil @controller.session["hello"]
|
168
152
|
end
|
169
153
|
|
170
|
-
|
154
|
+
should "return a hash with generic exception attributes as well as context data" do
|
171
155
|
exception_info = ExceptionInfo.new(@exception, @exception_context, @timestamp)
|
172
156
|
expected_data = {
|
173
157
|
"error_class" => "StandardError",
|
@@ -180,20 +164,20 @@ module ExceptionHandling
|
|
180
164
|
"location" => { "file" => "<no backtrace>", "line" => nil }
|
181
165
|
}
|
182
166
|
|
183
|
-
|
167
|
+
assert_equal_with_diff expected_data, prepare_data(exception_info.enhanced_data)
|
184
168
|
end
|
185
169
|
|
186
|
-
|
170
|
+
should "generate exception data appropriately if exception message is nil" do
|
187
171
|
exception_with_nil_message = RuntimeError.new(nil)
|
188
|
-
|
172
|
+
stub(exception_with_nil_message).message { nil }
|
189
173
|
exception_info = ExceptionInfo.new(exception_with_nil_message, @exception_context, @timestamp)
|
190
174
|
exception_data = exception_info.enhanced_data
|
191
|
-
|
192
|
-
|
175
|
+
assert_equal "RuntimeError: ", exception_data["error_string"]
|
176
|
+
assert_equal "RuntimeError: ", exception_data["error"]
|
193
177
|
end
|
194
178
|
|
195
|
-
|
196
|
-
exception_info = ExceptionInfo.new(@exception, @exception_context, @timestamp,
|
179
|
+
should "include controller data when available" do
|
180
|
+
exception_info = ExceptionInfo.new(@exception, @exception_context, @timestamp, @controller)
|
197
181
|
expected_data = {
|
198
182
|
"error_class" => "StandardError",
|
199
183
|
"error_string" => "StandardError: something went wrong",
|
@@ -210,10 +194,10 @@ module ExceptionHandling
|
|
210
194
|
"location" => { "controller" => "dummy", "action" => "fail", "file" => "<no backtrace>", "line" => nil }
|
211
195
|
}
|
212
196
|
|
213
|
-
|
197
|
+
assert_equal_with_diff expected_data, prepare_data(exception_info.enhanced_data)
|
214
198
|
end
|
215
199
|
|
216
|
-
|
200
|
+
should "extract controller from rack specific exception context when not provided explicitly" do
|
217
201
|
@exception_context["action_controller.instance"] = @controller
|
218
202
|
exception_info = ExceptionInfo.new(@exception, @exception_context, @timestamp)
|
219
203
|
expected_data = {
|
@@ -232,11 +216,11 @@ module ExceptionHandling
|
|
232
216
|
"location" => { "controller" => "dummy", "action" => "fail", "file" => "<no backtrace>", "line" => nil }
|
233
217
|
}
|
234
218
|
|
235
|
-
|
219
|
+
assert_equal_with_diff expected_data, prepare_data(exception_info.enhanced_data)
|
236
220
|
end
|
237
221
|
|
238
|
-
|
239
|
-
exception_info = ExceptionInfo.new(@exception, @exception_context, @timestamp,
|
222
|
+
should "add to_s attribute to specific sections that have their content in hash format" do
|
223
|
+
exception_info = ExceptionInfo.new(@exception, @exception_context, @timestamp, @controller)
|
240
224
|
expected_data = {
|
241
225
|
"error_class" => "StandardError",
|
242
226
|
"error_string" => "StandardError: something went wrong",
|
@@ -261,13 +245,13 @@ module ExceptionHandling
|
|
261
245
|
"location" => { "controller" => "dummy", "action" => "fail", "file" => "<no backtrace>", "line" => nil }
|
262
246
|
}
|
263
247
|
|
264
|
-
|
248
|
+
assert_equal_with_diff expected_data, exception_info.enhanced_data
|
265
249
|
end
|
266
250
|
|
267
|
-
|
251
|
+
should "filter out sensitive parameters like passwords" do
|
268
252
|
@controller.request.parameters[:password] = "super_secret"
|
269
253
|
@controller.request.parameters[:user] = { "password" => "also super secret", "password_confirmation" => "also super secret" }
|
270
|
-
exception_info = ExceptionInfo.new(@exception, @exception_context, @timestamp,
|
254
|
+
exception_info = ExceptionInfo.new(@exception, @exception_context, @timestamp, @controller)
|
271
255
|
expected_params = {
|
272
256
|
"password" => "[FILTERED]",
|
273
257
|
"advertiser_id" => 435, "controller" => "dummy",
|
@@ -277,11 +261,11 @@ module ExceptionHandling
|
|
277
261
|
"password_confirmation" => "[FILTERED]"
|
278
262
|
}
|
279
263
|
}
|
280
|
-
|
264
|
+
assert_equal_with_diff expected_params, exception_info.enhanced_data["request"]["params"]
|
281
265
|
end
|
282
266
|
|
283
|
-
|
284
|
-
exception_info = ExceptionInfo.new(@exception, @exception_context, @timestamp,
|
267
|
+
should "include the changes from the custom data callback" do
|
268
|
+
exception_info = ExceptionInfo.new(@exception, @exception_context, @timestamp, nil, @data_callback)
|
285
269
|
expected_data = {
|
286
270
|
"error_class" => "StandardError",
|
287
271
|
"error_string" => "StandardError: something went wrong",
|
@@ -294,11 +278,11 @@ module ExceptionHandling
|
|
294
278
|
"location" => { "file" => "<no backtrace>", "line" => nil }
|
295
279
|
}
|
296
280
|
|
297
|
-
|
281
|
+
assert_equal_with_diff expected_data, prepare_data(exception_info.enhanced_data)
|
298
282
|
end
|
299
283
|
|
300
|
-
|
301
|
-
|
284
|
+
should "apply the custom_data_hook results" do
|
285
|
+
stub(ExceptionHandling).custom_data_hook { ->(data) { data[:custom_hook] = "changes from custom hook" } }
|
302
286
|
exception_info = ExceptionInfo.new(@exception, @exception_context, @timestamp)
|
303
287
|
expected_data = {
|
304
288
|
"error_class" => "StandardError",
|
@@ -312,61 +296,61 @@ module ExceptionHandling
|
|
312
296
|
"location" => { "file" => "<no backtrace>", "line" => nil }
|
313
297
|
}
|
314
298
|
|
315
|
-
|
299
|
+
assert_equal_with_diff expected_data, prepare_data(exception_info.enhanced_data)
|
316
300
|
end
|
317
301
|
|
318
|
-
|
302
|
+
should "log info if the custom data hook results in a nil message exception" do
|
319
303
|
ExceptionHandling.custom_data_hook = ->(_data) do
|
320
304
|
raise_exception_with_nil_message
|
321
305
|
end
|
322
306
|
log_info_messages = []
|
323
|
-
|
307
|
+
stub(ExceptionHandling.logger).info.with_any_args do |message, _|
|
324
308
|
log_info_messages << message
|
325
309
|
end
|
326
310
|
|
327
311
|
exception_info = ExceptionInfo.new(@exception, @exception_context, @timestamp)
|
328
312
|
exception_info.enhanced_data
|
329
|
-
|
313
|
+
assert log_info_messages.find { |message| message =~ /Unable to execute custom custom_data_hook callback/ }
|
330
314
|
ExceptionHandling.custom_data_hook = nil
|
331
315
|
end
|
332
316
|
end
|
333
317
|
|
334
318
|
context "exception_description" do
|
335
|
-
|
319
|
+
should "return the exception description from the global exception filter list" do
|
336
320
|
exception = StandardError.new("No route matches")
|
337
321
|
exception_info = ExceptionInfo.new(exception, {}, Time.now)
|
338
322
|
description = exception_info.exception_description
|
339
|
-
|
340
|
-
|
323
|
+
assert_not_nil description
|
324
|
+
assert_equal :NoRoute, description.filter_name
|
341
325
|
end
|
342
326
|
|
343
|
-
|
327
|
+
should "find the description when filter criteria includes section in hash format" do
|
344
328
|
env = { server: "fe98" }
|
345
329
|
parameters = { advertiser_id: 435, controller: "sessions", action: "fail" }
|
346
330
|
session = { username: "jsmith", id: "session_key" }
|
347
331
|
request_uri = "host/path"
|
348
332
|
controller = create_dummy_controller(env, parameters, session, request_uri)
|
349
333
|
exception = StandardError.new("Request to click domain rejected")
|
350
|
-
exception_info = ExceptionInfo.new(exception,
|
351
|
-
|
334
|
+
exception_info = ExceptionInfo.new(exception, {}, Time.now, controller)
|
335
|
+
assert_equal true, exception_info.enhanced_data[:request].is_a?(Hash)
|
352
336
|
description = exception_info.exception_description
|
353
|
-
|
354
|
-
|
337
|
+
assert_not_nil description
|
338
|
+
assert_equal :"Click Request Rejected", description.filter_name
|
355
339
|
end
|
356
340
|
|
357
|
-
|
341
|
+
should "return same description object for related errors (avoid reloading exception catalog from disk)" do
|
358
342
|
exception = StandardError.new("No route matches")
|
359
|
-
exception_info = ExceptionInfo.new(exception,
|
343
|
+
exception_info = ExceptionInfo.new(exception, {}, Time.now)
|
360
344
|
description = exception_info.exception_description
|
361
345
|
|
362
346
|
repeat_ex = StandardError.new("No route matches 2")
|
363
|
-
repeat_ex_info = ExceptionInfo.new(repeat_ex,
|
364
|
-
|
347
|
+
repeat_ex_info = ExceptionInfo.new(repeat_ex, {}, Time.now)
|
348
|
+
assert_equal description.object_id, repeat_ex_info.exception_description.object_id
|
365
349
|
end
|
366
350
|
end
|
367
351
|
|
368
352
|
context "controller_name" do
|
369
|
-
|
353
|
+
setup do
|
370
354
|
@exception = StandardError.new('something went wrong')
|
371
355
|
@timestamp = Time.now
|
372
356
|
@exception_context = {
|
@@ -378,113 +362,73 @@ module ExceptionHandling
|
|
378
362
|
}
|
379
363
|
end
|
380
364
|
|
381
|
-
|
382
|
-
allow(ExceptionHandling.logger).to receive(:current_context_for_thread).and_return({ honeybadger_grouping: 'Group 1' })
|
383
|
-
exception_info = ExceptionInfo.new(@exception, @exception_context, @timestamp)
|
384
|
-
|
385
|
-
expect(exception_info.controller_name).to eq('Group 1')
|
386
|
-
end
|
387
|
-
|
388
|
-
it "returns honeybadger_grouping from log context even if controller is defined" do
|
389
|
-
allow(ExceptionHandling.logger).to receive(:current_context_for_thread).and_return({ honeybadger_grouping: 'Group 1' })
|
390
|
-
|
365
|
+
should "return controller_name when controller is present" do
|
391
366
|
env = { server: 'fe98' }
|
392
367
|
parameters = { controller: 'some_controller' }
|
393
368
|
session = { username: 'smith' }
|
394
369
|
request_uri = "host/path"
|
395
370
|
controller = create_dummy_controller(env, parameters, session, request_uri)
|
396
|
-
exception_info = ExceptionInfo.new(@exception, @exception_context, @timestamp, controller
|
371
|
+
exception_info = ExceptionInfo.new(@exception, @exception_context, @timestamp, controller)
|
397
372
|
|
398
|
-
|
373
|
+
assert_equal 'some_controller', exception_info.controller_name
|
399
374
|
end
|
400
375
|
|
401
|
-
|
402
|
-
env = { server: 'fe98' }
|
403
|
-
parameters = { controller: 'some_controller' }
|
404
|
-
session = { username: 'smith' }
|
405
|
-
request_uri = "host/path"
|
406
|
-
controller = create_dummy_controller(env, parameters, session, request_uri)
|
407
|
-
exception_info = ExceptionInfo.new(@exception, @exception_context, @timestamp, controller: controller)
|
408
|
-
|
409
|
-
expect(exception_info.controller_name).to eq('some_controller')
|
410
|
-
end
|
411
|
-
|
412
|
-
it "return an empty string when controller is not present" do
|
376
|
+
should "return an empty string when controller is not present" do
|
413
377
|
exception_info = ExceptionInfo.new(@exception, @exception_context, @timestamp)
|
414
378
|
|
415
|
-
|
379
|
+
assert_equal '', exception_info.controller_name
|
416
380
|
end
|
417
381
|
end
|
418
382
|
|
419
383
|
context "send_to_honeybadger?" do
|
420
|
-
|
421
|
-
|
384
|
+
should "be enabled when Honeybadger is defined and exception is not in the filter list" do
|
385
|
+
stub(ExceptionHandling).honeybadger_defined? { true }
|
422
386
|
exception = StandardError.new("something went wrong")
|
423
|
-
exception_info = ExceptionInfo.new(exception,
|
424
|
-
|
425
|
-
|
387
|
+
exception_info = ExceptionInfo.new(exception, {}, Time.now)
|
388
|
+
assert_nil exception_info.exception_description
|
389
|
+
assert_equal true, exception_info.send_to_honeybadger?
|
426
390
|
end
|
427
391
|
|
428
|
-
|
429
|
-
|
392
|
+
should "be enabled when Honeybadger is defined and exception is on the filter list with the flag turned on" do
|
393
|
+
stub(ExceptionHandling).honeybadger_defined? { true }
|
430
394
|
exception = StandardError.new("No route matches")
|
431
|
-
exception_info = ExceptionInfo.new(exception,
|
432
|
-
|
433
|
-
|
434
|
-
|
395
|
+
exception_info = ExceptionInfo.new(exception, {}, Time.now)
|
396
|
+
assert_not_nil exception_info.exception_description
|
397
|
+
assert_equal true, exception_info.exception_description.send_to_honeybadger
|
398
|
+
assert_equal true, exception_info.send_to_honeybadger?
|
435
399
|
end
|
436
400
|
|
437
|
-
|
438
|
-
|
401
|
+
should "be disabled when Honeybadger is defined and exception is on the filter list with the flag turned off" do
|
402
|
+
stub(ExceptionHandling).honeybadger_defined? { true }
|
439
403
|
exception = StandardError.new("No route matches")
|
440
|
-
exception_info = ExceptionInfo.new(exception,
|
441
|
-
|
442
|
-
|
443
|
-
|
404
|
+
exception_info = ExceptionInfo.new(exception, {}, Time.now)
|
405
|
+
assert_not_nil exception_info.exception_description
|
406
|
+
stub(exception_info.exception_description).send_to_honeybadger { false }
|
407
|
+
assert_equal false, exception_info.send_to_honeybadger?
|
444
408
|
end
|
445
409
|
|
446
|
-
|
447
|
-
|
410
|
+
should "be disabled when Honeybadger is not defined" do
|
411
|
+
stub(ExceptionHandling).honeybadger_defined? { false }
|
448
412
|
exception = StandardError.new("something went wrong")
|
449
|
-
exception_info = ExceptionInfo.new(exception,
|
450
|
-
|
451
|
-
|
413
|
+
exception_info = ExceptionInfo.new(exception, {}, Time.now)
|
414
|
+
assert_nil exception_info.exception_description
|
415
|
+
assert_equal false, exception_info.send_to_honeybadger?
|
452
416
|
end
|
453
417
|
end
|
454
418
|
|
455
419
|
context "honeybadger_context_data" do
|
456
|
-
|
457
|
-
allow(ExceptionHandling.logger).to receive(:current_context_for_thread).and_return({ cuid: 'ABCD' })
|
458
|
-
end
|
459
|
-
|
460
|
-
it "include thread_context when log_context: is nil" do
|
461
|
-
exception_with_nil_message = RuntimeError.new(nil)
|
462
|
-
allow(exception_with_nil_message).to receive(:message).and_return(nil)
|
463
|
-
exception_info = ExceptionInfo.new(exception_with_nil_message, @exception_context, @timestamp)
|
464
|
-
honeybadger_context_data = exception_info.honeybadger_context_data
|
465
|
-
expect(honeybadger_context_data[:log_context]).to eq({ "cuid" => 'ABCD' })
|
466
|
-
end
|
467
|
-
|
468
|
-
it "include thread context merged with log_context:" do
|
469
|
-
exception_with_nil_message = RuntimeError.new(nil)
|
470
|
-
allow(exception_with_nil_message).to receive(:message).and_return(nil)
|
471
|
-
exception_info = ExceptionInfo.new(exception_with_nil_message, @exception_context, @timestamp, log_context: { url: 'http://example.com' })
|
472
|
-
honeybadger_context_data = exception_info.honeybadger_context_data
|
473
|
-
expect(honeybadger_context_data[:log_context]).to eq({ "cuid" => 'ABCD', "url" => 'http://example.com' })
|
474
|
-
end
|
475
|
-
|
476
|
-
it "return the error details and relevant context data to be used as honeybadger notification context while filtering sensitive data" do
|
420
|
+
should "return the error details and relevant context data to be used as honeybadger notification context while filtering sensitive data" do
|
477
421
|
env = { server: "fe98" }
|
478
422
|
parameters = { advertiser_id: 435 }
|
479
423
|
session = { username: "jsmith" }
|
480
424
|
request_uri = "host/path"
|
481
425
|
controller = create_dummy_controller(env, parameters, session, request_uri)
|
482
|
-
|
426
|
+
stub(ExceptionHandling).server_name { "invoca_fe98" }
|
483
427
|
|
484
428
|
exception = StandardError.new("Some Exception")
|
485
429
|
exception.set_backtrace([
|
486
|
-
"
|
487
|
-
"
|
430
|
+
"test/unit/exception_handling_test.rb:847:in `exception_1'",
|
431
|
+
"test/unit/exception_handling_test.rb:455:in `block (4 levels) in <class:ExceptionHandlingTest>'"
|
488
432
|
])
|
489
433
|
exception_context = { "SERVER_NAME" => "exceptional.com" }
|
490
434
|
data_callback = ->(data) do
|
@@ -494,7 +438,7 @@ module ExceptionHandling
|
|
494
438
|
data[:other_section] = "This should not be included in the response"
|
495
439
|
end
|
496
440
|
timestamp = Time.now
|
497
|
-
exception_info = ExceptionInfo.new(exception, exception_context, timestamp, controller
|
441
|
+
exception_info = ExceptionInfo.new(exception, exception_context, timestamp, controller, data_callback)
|
498
442
|
|
499
443
|
expected_data = {
|
500
444
|
timestamp: timestamp,
|
@@ -502,6 +446,7 @@ module ExceptionHandling
|
|
502
446
|
exception_context: { "SERVER_NAME" => "exceptional.com" },
|
503
447
|
server: "invoca_fe98",
|
504
448
|
scm_revision: "5b24eac37aaa91f5784901e9aabcead36fd9df82",
|
449
|
+
notes: "this is used by a test",
|
505
450
|
user_details: { "username" => "jsmith" },
|
506
451
|
request: {
|
507
452
|
"params" => { "advertiser_id" => 435 },
|
@@ -516,30 +461,28 @@ module ExceptionHandling
|
|
516
461
|
"SERVER_NAME" => "exceptional.com"
|
517
462
|
},
|
518
463
|
backtrace: [
|
519
|
-
"
|
520
|
-
"
|
464
|
+
"test/unit/exception_handling_test.rb:847:in `exception_1'",
|
465
|
+
"test/unit/exception_handling_test.rb:455:in `block (4 levels) in <class:ExceptionHandlingTest>'"
|
521
466
|
],
|
522
|
-
event_response: "Event successfully received"
|
523
|
-
log_context: { "cuid" => "ABCD" },
|
524
|
-
notes: "this is used by a test"
|
467
|
+
event_response: "Event successfully received"
|
525
468
|
}
|
526
|
-
|
469
|
+
assert_equal_with_diff expected_data, exception_info.honeybadger_context_data
|
527
470
|
end
|
528
471
|
|
529
472
|
[['Hash', { 'cookie' => 'cookie_context' }],
|
530
473
|
['String', 'Entering Error State'],
|
531
474
|
['Array', ['Error1', 'Error2']]].each do |klass, value|
|
532
|
-
|
475
|
+
should "extract context from exception_context when it is a #{klass}" do
|
533
476
|
exception = StandardError.new("Exception")
|
534
477
|
exception_context = value
|
535
478
|
exception_info = ExceptionInfo.new(exception, exception_context, Time.now)
|
536
479
|
|
537
|
-
|
538
|
-
|
480
|
+
assert_equal klass, value.class.name
|
481
|
+
assert_equal value, exception_info.honeybadger_context_data[:exception_context]
|
539
482
|
end
|
540
483
|
end
|
541
484
|
|
542
|
-
|
485
|
+
should "filter out sensitive data from exception context such as [password, password_confirmation, oauth_token]" do
|
543
486
|
sensitive_data = {
|
544
487
|
"password" => "super_secret",
|
545
488
|
"password_confirmation" => "super_secret_confirmation",
|
@@ -574,14 +517,15 @@ module ExceptionHandling
|
|
574
517
|
}
|
575
518
|
}.merge(expected_sensitive_data)
|
576
519
|
|
577
|
-
|
520
|
+
assert_equal_with_diff expected_exception_context, exception_info.honeybadger_context_data[:exception_context]
|
578
521
|
end
|
579
522
|
|
580
|
-
|
523
|
+
should "omit context if exception_context is empty" do
|
581
524
|
exception = StandardError.new("Exception")
|
582
525
|
exception_context = ""
|
583
526
|
exception_info = ExceptionInfo.new(exception, exception_context, Time.now)
|
584
|
-
|
527
|
+
|
528
|
+
assert_nil exception_info.honeybadger_context_data[:exception_context]
|
585
529
|
end
|
586
530
|
end
|
587
531
|
|