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.
Files changed (37) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -1
  3. data/.jenkins/Jenkinsfile +24 -8
  4. data/.rspec +3 -0
  5. data/CHANGELOG.md +19 -2
  6. data/Gemfile +4 -4
  7. data/Gemfile.lock +67 -58
  8. data/Rakefile +7 -6
  9. data/gemfiles/rails_4.gemfile +4 -4
  10. data/gemfiles/rails_5.gemfile +4 -4
  11. data/gemfiles/rails_6.gemfile +4 -4
  12. data/lib/exception_handling.rb +5 -2
  13. data/lib/exception_handling/exception_info.rb +3 -6
  14. data/lib/exception_handling/log_stub_error.rb +2 -1
  15. data/lib/exception_handling/logging_methods.rb +27 -0
  16. data/lib/exception_handling/methods.rb +6 -53
  17. data/lib/exception_handling/testing.rb +20 -10
  18. data/lib/exception_handling/version.rb +1 -1
  19. data/{test → spec}/helpers/controller_helpers.rb +0 -0
  20. data/{test → spec}/helpers/exception_helpers.rb +2 -2
  21. data/{test → spec}/rake_test_warning_false.rb +0 -0
  22. data/{test/test_helper.rb → spec/spec_helper.rb} +50 -39
  23. data/spec/unit/exception_handling/exception_catalog_spec.rb +85 -0
  24. data/spec/unit/exception_handling/exception_description_spec.rb +82 -0
  25. data/{test/unit/exception_handling/exception_info_test.rb → spec/unit/exception_handling/exception_info_spec.rb} +118 -99
  26. data/{test/unit/exception_handling/honeybadger_callbacks_test.rb → spec/unit/exception_handling/honeybadger_callbacks_spec.rb} +20 -20
  27. data/{test/unit/exception_handling/log_error_stub_test.rb → spec/unit/exception_handling/log_error_stub_spec.rb} +38 -22
  28. data/spec/unit/exception_handling/logging_methods_spec.rb +38 -0
  29. data/{test/unit/exception_handling/mailer_test.rb → spec/unit/exception_handling/mailer_spec.rb} +17 -17
  30. data/spec/unit/exception_handling/methods_spec.rb +105 -0
  31. data/spec/unit/exception_handling/sensu_spec.rb +51 -0
  32. data/{test/unit/exception_handling_test.rb → spec/unit/exception_handling_spec.rb} +348 -329
  33. metadata +32 -28
  34. data/test/unit/exception_handling/exception_catalog_test.rb +0 -85
  35. data/test/unit/exception_handling/exception_description_test.rb +0 -82
  36. data/test/unit/exception_handling/methods_test.rb +0 -84
  37. 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.5.1.pre.1
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-08-25 00:00:00.000000000 Z
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
- - test/helpers/controller_helpers.rb
152
- - test/helpers/exception_helpers.rb
153
- - test/rake_test_warning_false.rb
154
- - test/test_helper.rb
155
- - test/unit/exception_handling/exception_catalog_test.rb
156
- - test/unit/exception_handling/exception_description_test.rb
157
- - test/unit/exception_handling/exception_info_test.rb
158
- - test/unit/exception_handling/honeybadger_callbacks_test.rb
159
- - test/unit/exception_handling/log_error_stub_test.rb
160
- - test/unit/exception_handling/mailer_test.rb
161
- - test/unit/exception_handling/methods_test.rb
162
- - test/unit/exception_handling/sensu_test.rb
163
- - test/unit/exception_handling_test.rb
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
- - test/helpers/controller_helpers.rb
194
- - test/helpers/exception_helpers.rb
195
- - test/rake_test_warning_false.rb
196
- - test/test_helper.rb
197
- - test/unit/exception_handling/exception_catalog_test.rb
198
- - test/unit/exception_handling/exception_description_test.rb
199
- - test/unit/exception_handling/exception_info_test.rb
200
- - test/unit/exception_handling/honeybadger_callbacks_test.rb
201
- - test/unit/exception_handling/log_error_stub_test.rb
202
- - test/unit/exception_handling/mailer_test.rb
203
- - test/unit/exception_handling/methods_test.rb
204
- - test/unit/exception_handling/sensu_test.rb
205
- - test/unit/exception_handling_test.rb
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