exception_handling 2.5.1.pre.1 → 2.8.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 +4 -4
- data/.gitignore +1 -1
- data/.jenkins/Jenkinsfile +24 -8
- data/.rspec +3 -0
- data/CHANGELOG.md +19 -2
- data/Gemfile +4 -4
- data/Gemfile.lock +67 -58
- data/Rakefile +7 -6
- data/gemfiles/rails_4.gemfile +4 -4
- data/gemfiles/rails_5.gemfile +4 -4
- data/gemfiles/rails_6.gemfile +4 -4
- data/lib/exception_handling.rb +5 -2
- data/lib/exception_handling/exception_info.rb +3 -6
- data/lib/exception_handling/log_stub_error.rb +2 -1
- data/lib/exception_handling/logging_methods.rb +27 -0
- data/lib/exception_handling/methods.rb +6 -53
- data/lib/exception_handling/testing.rb +20 -10
- data/lib/exception_handling/version.rb +1 -1
- data/{test → spec}/helpers/controller_helpers.rb +0 -0
- data/{test → spec}/helpers/exception_helpers.rb +2 -2
- data/{test → spec}/rake_test_warning_false.rb +0 -0
- data/{test/test_helper.rb → spec/spec_helper.rb} +50 -39
- data/spec/unit/exception_handling/exception_catalog_spec.rb +85 -0
- data/spec/unit/exception_handling/exception_description_spec.rb +82 -0
- data/{test/unit/exception_handling/exception_info_test.rb → spec/unit/exception_handling/exception_info_spec.rb} +118 -99
- data/{test/unit/exception_handling/honeybadger_callbacks_test.rb → spec/unit/exception_handling/honeybadger_callbacks_spec.rb} +20 -20
- data/{test/unit/exception_handling/log_error_stub_test.rb → spec/unit/exception_handling/log_error_stub_spec.rb} +38 -22
- data/spec/unit/exception_handling/logging_methods_spec.rb +38 -0
- data/{test/unit/exception_handling/mailer_test.rb → spec/unit/exception_handling/mailer_spec.rb} +17 -17
- data/spec/unit/exception_handling/methods_spec.rb +105 -0
- data/spec/unit/exception_handling/sensu_spec.rb +51 -0
- data/{test/unit/exception_handling_test.rb → spec/unit/exception_handling_spec.rb} +348 -329
- metadata +32 -28
- data/test/unit/exception_handling/exception_catalog_test.rb +0 -85
- data/test/unit/exception_handling/exception_description_test.rb +0 -82
- data/test/unit/exception_handling/methods_test.rb +0 -84
- data/test/unit/exception_handling/sensu_test.rb +0 -52
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: exception_handling
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.8.0.pre.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Invoca
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-10-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: actionmailer
|
@@ -122,6 +122,7 @@ files:
|
|
122
122
|
- ".gitignore"
|
123
123
|
- ".jenkins/Jenkinsfile"
|
124
124
|
- ".jenkins/ruby_build_pod.yml"
|
125
|
+
- ".rspec"
|
125
126
|
- ".rubocop.yml"
|
126
127
|
- ".ruby-version"
|
127
128
|
- Appraisals
|
@@ -143,24 +144,26 @@ files:
|
|
143
144
|
- lib/exception_handling/exception_info.rb
|
144
145
|
- lib/exception_handling/honeybadger_callbacks.rb
|
145
146
|
- lib/exception_handling/log_stub_error.rb
|
147
|
+
- lib/exception_handling/logging_methods.rb
|
146
148
|
- lib/exception_handling/mailer.rb
|
147
149
|
- lib/exception_handling/methods.rb
|
148
150
|
- lib/exception_handling/sensu.rb
|
149
151
|
- lib/exception_handling/testing.rb
|
150
152
|
- lib/exception_handling/version.rb
|
151
|
-
-
|
152
|
-
-
|
153
|
-
-
|
154
|
-
-
|
155
|
-
-
|
156
|
-
-
|
157
|
-
-
|
158
|
-
-
|
159
|
-
-
|
160
|
-
-
|
161
|
-
-
|
162
|
-
-
|
163
|
-
-
|
153
|
+
- spec/helpers/controller_helpers.rb
|
154
|
+
- spec/helpers/exception_helpers.rb
|
155
|
+
- spec/rake_test_warning_false.rb
|
156
|
+
- spec/spec_helper.rb
|
157
|
+
- spec/unit/exception_handling/exception_catalog_spec.rb
|
158
|
+
- spec/unit/exception_handling/exception_description_spec.rb
|
159
|
+
- spec/unit/exception_handling/exception_info_spec.rb
|
160
|
+
- spec/unit/exception_handling/honeybadger_callbacks_spec.rb
|
161
|
+
- spec/unit/exception_handling/log_error_stub_spec.rb
|
162
|
+
- spec/unit/exception_handling/logging_methods_spec.rb
|
163
|
+
- spec/unit/exception_handling/mailer_spec.rb
|
164
|
+
- spec/unit/exception_handling/methods_spec.rb
|
165
|
+
- spec/unit/exception_handling/sensu_spec.rb
|
166
|
+
- spec/unit/exception_handling_spec.rb
|
164
167
|
- views/exception_handling/mailer/escalate_custom.html.erb
|
165
168
|
- views/exception_handling/mailer/escalation_notification.html.erb
|
166
169
|
- views/exception_handling/mailer/log_parser_exception_notification.html.erb
|
@@ -190,16 +193,17 @@ specification_version: 4
|
|
190
193
|
summary: Invoca's exception handling logger/emailer layer, based on exception_notifier.
|
191
194
|
Works with Rails or EventMachine or EventMachine+Synchrony.
|
192
195
|
test_files:
|
193
|
-
-
|
194
|
-
-
|
195
|
-
-
|
196
|
-
-
|
197
|
-
-
|
198
|
-
-
|
199
|
-
-
|
200
|
-
-
|
201
|
-
-
|
202
|
-
-
|
203
|
-
-
|
204
|
-
-
|
205
|
-
-
|
196
|
+
- spec/helpers/controller_helpers.rb
|
197
|
+
- spec/helpers/exception_helpers.rb
|
198
|
+
- spec/rake_test_warning_false.rb
|
199
|
+
- spec/spec_helper.rb
|
200
|
+
- spec/unit/exception_handling/exception_catalog_spec.rb
|
201
|
+
- spec/unit/exception_handling/exception_description_spec.rb
|
202
|
+
- spec/unit/exception_handling/exception_info_spec.rb
|
203
|
+
- spec/unit/exception_handling/honeybadger_callbacks_spec.rb
|
204
|
+
- spec/unit/exception_handling/log_error_stub_spec.rb
|
205
|
+
- spec/unit/exception_handling/logging_methods_spec.rb
|
206
|
+
- spec/unit/exception_handling/mailer_spec.rb
|
207
|
+
- spec/unit/exception_handling/methods_spec.rb
|
208
|
+
- spec/unit/exception_handling/sensu_spec.rb
|
209
|
+
- spec/unit/exception_handling_spec.rb
|
@@ -1,85 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require File.expand_path('../../test_helper', __dir__)
|
4
|
-
|
5
|
-
module ExceptionHandling
|
6
|
-
class ExceptionCatalogTest < ActiveSupport::TestCase
|
7
|
-
|
8
|
-
context "With stubbed yaml content" do
|
9
|
-
setup do
|
10
|
-
filter_list = { exception1: { error: "my error message" },
|
11
|
-
exception2: { error: "some other message", session: "misc data" } }
|
12
|
-
stub(YAML).load_file { filter_list }
|
13
|
-
|
14
|
-
# bump modified time up to get the above filter loaded
|
15
|
-
stub(File).mtime { incrementing_mtime }
|
16
|
-
end
|
17
|
-
|
18
|
-
context "with loaded data" do
|
19
|
-
setup do
|
20
|
-
stub(File).mtime { incrementing_mtime }
|
21
|
-
@exception_catalog = ExceptionCatalog.new(ExceptionHandling.filter_list_filename)
|
22
|
-
@exception_catalog.send :load_file
|
23
|
-
end
|
24
|
-
|
25
|
-
should "have loaded filters" do
|
26
|
-
assert_equal 2, @exception_catalog.instance_eval("@filters").size
|
27
|
-
end
|
28
|
-
|
29
|
-
should "find messages in the catalog" do
|
30
|
-
assert !@exception_catalog.find(error: "Scott says unlikely to ever match")
|
31
|
-
end
|
32
|
-
|
33
|
-
should "find matching data" do
|
34
|
-
exception_description = @exception_catalog.find(error: "this is my error message, which should match something")
|
35
|
-
assert exception_description
|
36
|
-
assert_equal :exception1, exception_description.filter_name
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
should "write errors loading the yaml file directly to the log file" do
|
41
|
-
@exception_catalog = ExceptionCatalog.new(ExceptionHandling.filter_list_filename)
|
42
|
-
|
43
|
-
mock(ExceptionHandling).log_error.never
|
44
|
-
mock(ExceptionHandling).write_exception_to_log(anything, "ExceptionCatalog#refresh_filters: ./config/exception_filters.yml", anything)
|
45
|
-
mock(@exception_catalog).load_file { raise "noooooo" }
|
46
|
-
|
47
|
-
@exception_catalog.find({})
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
context "with live yaml content" do
|
52
|
-
setup do
|
53
|
-
@filename = File.expand_path('../../../config/exception_filters.yml', __dir__)
|
54
|
-
@exception_catalog = ExceptionCatalog.new(@filename)
|
55
|
-
assert_nothing_raised do
|
56
|
-
@exception_catalog.send :load_file
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
should "load the filter data" do
|
61
|
-
assert !@exception_catalog.find(error: "Scott says unlikely to ever match")
|
62
|
-
assert !@exception_catalog.find(error: "Scott says unlikely to ever match")
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
context "with no yaml content" do
|
67
|
-
setup do
|
68
|
-
@exception_catalog = ExceptionCatalog.new(nil)
|
69
|
-
end
|
70
|
-
|
71
|
-
should "not load filter data" do
|
72
|
-
mock(ExceptionHandling).write_exception_to_log.with_any_args.never
|
73
|
-
@exception_catalog.find(error: "Scott says unlikely to ever match")
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
private
|
78
|
-
|
79
|
-
def incrementing_mtime
|
80
|
-
@mtime ||= Time.now
|
81
|
-
@mtime += 1.day
|
82
|
-
end
|
83
|
-
|
84
|
-
end
|
85
|
-
end
|
@@ -1,82 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require File.expand_path('../../test_helper', __dir__)
|
4
|
-
|
5
|
-
module ExceptionHandling
|
6
|
-
class ExceptionDescriptionTest < ActiveSupport::TestCase
|
7
|
-
|
8
|
-
context "Filter" do
|
9
|
-
should "allow direct matching of strings" do
|
10
|
-
@f = ExceptionDescription.new(:filter1, error: "my error message")
|
11
|
-
assert @f.match?('error' => "my error message")
|
12
|
-
end
|
13
|
-
|
14
|
-
should "allow direct matching of strings on with symbol keys" do
|
15
|
-
@f = ExceptionDescription.new(:filter1, error: "my error message")
|
16
|
-
assert @f.match?(error: "my error message")
|
17
|
-
end
|
18
|
-
|
19
|
-
should "allow wildcards to cross line boundries" do
|
20
|
-
@f = ExceptionDescription.new(:filter1, error: "my error message.*with multiple lines")
|
21
|
-
assert @f.match?(error: "my error message\nwith more than one, with multiple lines")
|
22
|
-
end
|
23
|
-
|
24
|
-
should "complain when no regexps have a value" do
|
25
|
-
assert_raise(ArgumentError, "has all blank regexe") { ExceptionDescription.new(:filter1, error: nil) }
|
26
|
-
end
|
27
|
-
|
28
|
-
should "report when an invalid key is passed" do
|
29
|
-
assert_raise(ArgumentError, "Unknown section: not_a_parameter") { ExceptionDescription.new(:filter1, error: "my error message", not_a_parameter: false) }
|
30
|
-
end
|
31
|
-
|
32
|
-
should "allow send_to_honeybadger to be specified and have it disabled by default" do
|
33
|
-
assert !ExceptionDescription.new(:filter1, error: "my error message", send_to_honeybadger: false).send_to_honeybadger
|
34
|
-
assert ExceptionDescription.new(:filter1, error: "my error message", send_to_honeybadger: true).send_to_honeybadger
|
35
|
-
assert !ExceptionDescription.new(:filter1, error: "my error message").send_to_honeybadger
|
36
|
-
end
|
37
|
-
|
38
|
-
should "allow send_metric to be configured" do
|
39
|
-
assert !ExceptionDescription.new(:filter1, error: "my error message", send_metric: false).send_metric
|
40
|
-
assert ExceptionDescription.new(:filter1, error: "my error message").send_metric
|
41
|
-
end
|
42
|
-
|
43
|
-
should "provide metric name" do
|
44
|
-
assert_equal "filter1", ExceptionDescription.new(:filter1, error: "my error message").metric_name
|
45
|
-
assert_equal "some_other_metric_name", ExceptionDescription.new(:filter1, error: "my error message", metric_name: :some_other_metric_name).metric_name
|
46
|
-
end
|
47
|
-
|
48
|
-
should "replace spaces in metric name" do
|
49
|
-
@f = ExceptionDescription.new(:"filter has spaces", error: "my error message")
|
50
|
-
assert_equal "filter_has_spaces", @f.metric_name
|
51
|
-
end
|
52
|
-
|
53
|
-
should "allow notes to be recorded" do
|
54
|
-
assert_nil ExceptionDescription.new(:filter1, error: "my error message").notes
|
55
|
-
assert_equal "a long string", ExceptionDescription.new(:filter1, error: "my error message", notes: "a long string").notes
|
56
|
-
end
|
57
|
-
|
58
|
-
should "not consider config options in the filter set" do
|
59
|
-
assert ExceptionDescription.new(:filter1, error: "my error message", send_metric: false).match?(error: "my error message")
|
60
|
-
assert ExceptionDescription.new(:filter1, error: "my error message", metric_name: "false").match?(error: "my error message")
|
61
|
-
assert ExceptionDescription.new(:filter1, error: "my error message", notes: "hey").match?(error: "my error message")
|
62
|
-
end
|
63
|
-
|
64
|
-
should "provide exception details" do
|
65
|
-
exception_description = ExceptionDescription.new(:filter1, error: "my error message", notes: "hey")
|
66
|
-
|
67
|
-
expected = { "send_metric" => true, "metric_name" => "filter1", "notes" => "hey" }
|
68
|
-
|
69
|
-
assert_equal expected, exception_description.exception_data
|
70
|
-
end
|
71
|
-
|
72
|
-
should "match multiple email addresses" do
|
73
|
-
mobi = "ExceptionHandling::Warning: LoginAttempt::IPAddressLocked: failed login for 'mcc@mobistreak.com'"
|
74
|
-
credit = "ExceptionHandling::Warning: LoginAttempt::IPAddressLocked: failed login for 'damon@thecreditpros.com'"
|
75
|
-
|
76
|
-
exception_description = ExceptionDescription.new(:filter1, error: "ExceptionHandling::Warning: LoginAttempt::IPAddressLocked: failed login for '(mcc\@mobistreak|damon\@thecreditpros).com'")
|
77
|
-
assert exception_description.match?(error: mobi), "does not match mobi"
|
78
|
-
assert exception_description.match?(error: credit), "does not match credit"
|
79
|
-
end
|
80
|
-
end
|
81
|
-
end
|
82
|
-
end
|
@@ -1,84 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require File.expand_path('../../test_helper', __dir__)
|
4
|
-
|
5
|
-
require "exception_handling/testing"
|
6
|
-
|
7
|
-
module ExceptionHandling
|
8
|
-
class MethodsTest < ActiveSupport::TestCase
|
9
|
-
include ExceptionHelpers
|
10
|
-
|
11
|
-
def dont_stub_log_error
|
12
|
-
true
|
13
|
-
end
|
14
|
-
|
15
|
-
context "ExceptionHandling.Methods" do
|
16
|
-
setup do
|
17
|
-
@controller = Testing::ControllerStub.new
|
18
|
-
ExceptionHandling.stub_handler = nil
|
19
|
-
end
|
20
|
-
|
21
|
-
should "set the around filter" do
|
22
|
-
assert_equal :set_current_controller, Testing::ControllerStub.around_filter_method
|
23
|
-
assert_nil ExceptionHandling.current_controller
|
24
|
-
@controller.simulate_around_filter do
|
25
|
-
assert_equal @controller, ExceptionHandling.current_controller
|
26
|
-
end
|
27
|
-
assert_nil ExceptionHandling.current_controller
|
28
|
-
end
|
29
|
-
|
30
|
-
should "use the current_controller when available" do
|
31
|
-
capture_notifications
|
32
|
-
|
33
|
-
mock(ExceptionHandling.logger).fatal(/blah/, anything)
|
34
|
-
@controller.simulate_around_filter do
|
35
|
-
ExceptionHandling.log_error(ArgumentError.new("blah"))
|
36
|
-
assert_equal 1, sent_notifications.size, sent_notifications.inspect
|
37
|
-
assert_match(@controller.request.request_uri, sent_notifications.last.enhanced_data['request'].to_s)
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
should "report long running controller action" do
|
42
|
-
assert_equal 2, @controller.send(:long_controller_action_timeout)
|
43
|
-
mock(ExceptionHandling).log_error(/Long controller action detected in #{@controller.class.name.split("::").last}::test_action/, anything, anything)
|
44
|
-
@controller.simulate_around_filter do
|
45
|
-
sleep(3)
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
should "not report long running controller actions if it is less than the timeout" do
|
50
|
-
assert_equal 2, @controller.send(:long_controller_action_timeout)
|
51
|
-
stub(ExceptionHandling).log_error { flunk "Should not timeout" }
|
52
|
-
@controller.simulate_around_filter do
|
53
|
-
sleep(1)
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
should "default long running controller action(300/30 for test/prod)" do
|
58
|
-
class DummyController
|
59
|
-
include ExceptionHandling::Methods
|
60
|
-
end
|
61
|
-
|
62
|
-
controller = DummyController.new
|
63
|
-
|
64
|
-
Rails.env = 'production'
|
65
|
-
assert_equal 30, controller.send(:long_controller_action_timeout)
|
66
|
-
|
67
|
-
Rails.env = 'test'
|
68
|
-
assert_equal 300, controller.send(:long_controller_action_timeout)
|
69
|
-
end
|
70
|
-
|
71
|
-
context "#log_warning" do
|
72
|
-
should "be available to the controller" do
|
73
|
-
assert_equal true, @controller.methods.include?(:log_warning)
|
74
|
-
end
|
75
|
-
|
76
|
-
should "call ExceptionHandling#log_warning" do
|
77
|
-
mock(ExceptionHandling).log_warning("Hi mom")
|
78
|
-
@controller.send(:log_warning, "Hi mom")
|
79
|
-
end
|
80
|
-
end
|
81
|
-
end
|
82
|
-
|
83
|
-
end
|
84
|
-
end
|
@@ -1,52 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require File.expand_path('../../test_helper', __dir__)
|
4
|
-
|
5
|
-
module ExceptionHandling
|
6
|
-
class SensuTest < ActiveSupport::TestCase
|
7
|
-
context "#generate_event" do
|
8
|
-
should "create an event" do
|
9
|
-
mock(ExceptionHandling::Sensu).send_event(name: "world_is_ending", output: "stick head between knees and kiss ass goodbye", status: 1)
|
10
|
-
|
11
|
-
ExceptionHandling::Sensu.generate_event("world_is_ending", "stick head between knees and kiss ass goodbye")
|
12
|
-
end
|
13
|
-
|
14
|
-
should "add the sensu prefix" do
|
15
|
-
ExceptionHandling.sensu_prefix = "cnn_"
|
16
|
-
|
17
|
-
mock(ExceptionHandling::Sensu).send_event(name: "cnn_world_is_ending", output: "stick head between knees and kiss ass goodbye", status: 1)
|
18
|
-
|
19
|
-
ExceptionHandling::Sensu.generate_event("world_is_ending", "stick head between knees and kiss ass goodbye")
|
20
|
-
end
|
21
|
-
|
22
|
-
should "allow the level to be set to critical" do
|
23
|
-
mock(ExceptionHandling::Sensu).send_event(name: "world_is_ending", output: "stick head between knees and kiss ass goodbye", status: 2)
|
24
|
-
|
25
|
-
ExceptionHandling::Sensu.generate_event("world_is_ending", "stick head between knees and kiss ass goodbye", :critical)
|
26
|
-
end
|
27
|
-
|
28
|
-
should "error if an invalid level is supplied" do
|
29
|
-
dont_allow(ExceptionHandling::Sensu).send_event
|
30
|
-
|
31
|
-
assert_raise(RuntimeError, "Invalid alert level") do
|
32
|
-
ExceptionHandling::Sensu.generate_event("world_is_ending", "stick head between knees and kiss ass goodbye", :hair_on_fire)
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
context "#send_event" do
|
38
|
-
setup do
|
39
|
-
@event = { name: "world_is_ending", output: "stick head between knees and kiss ass goodbye", status: 1 }
|
40
|
-
@socket = SocketStub.new
|
41
|
-
end
|
42
|
-
|
43
|
-
should "send event json to sensu client" do
|
44
|
-
mock.any_instance_of(Addrinfo).connect.with_any_args { @socket }
|
45
|
-
|
46
|
-
ExceptionHandling::Sensu.send_event(@event)
|
47
|
-
|
48
|
-
assert_equal @event.to_json, @socket.sent.first
|
49
|
-
end
|
50
|
-
end
|
51
|
-
end
|
52
|
-
end
|