exception_handling 2.17.0.pre.tstarck.1 → 3.0.pre.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +0 -3
  3. data/.ruby-version +1 -1
  4. data/Gemfile +16 -12
  5. data/Gemfile.lock +138 -153
  6. data/README.md +21 -90
  7. data/Rakefile +11 -8
  8. data/exception_handling.gemspec +10 -14
  9. data/lib/exception_handling/exception_info.rb +11 -15
  10. data/lib/exception_handling/honeybadger_callbacks.rb +59 -0
  11. data/lib/exception_handling/log_stub_error.rb +1 -2
  12. data/lib/exception_handling/methods.rb +53 -6
  13. data/lib/exception_handling/testing.rb +10 -20
  14. data/lib/exception_handling/version.rb +1 -1
  15. data/lib/exception_handling.rb +34 -135
  16. data/semaphore_ci/setup.sh +3 -0
  17. data/{spec → test}/helpers/exception_helpers.rb +2 -2
  18. data/{spec/spec_helper.rb → test/test_helper.rb} +45 -75
  19. data/test/unit/exception_handling/exception_catalog_test.rb +85 -0
  20. data/test/unit/exception_handling/exception_description_test.rb +82 -0
  21. data/{spec/unit/exception_handling/exception_info_spec.rb → test/unit/exception_handling/exception_info_test.rb} +114 -170
  22. data/test/unit/exception_handling/honeybadger_callbacks_test.rb +122 -0
  23. data/{spec/unit/exception_handling/log_error_stub_spec.rb → test/unit/exception_handling/log_error_stub_test.rb} +22 -38
  24. data/{spec/unit/exception_handling/mailer_spec.rb → test/unit/exception_handling/mailer_test.rb} +18 -17
  25. data/test/unit/exception_handling/methods_test.rb +84 -0
  26. data/test/unit/exception_handling/sensu_test.rb +52 -0
  27. data/test/unit/exception_handling_test.rb +1109 -0
  28. metadata +59 -99
  29. data/.github/CODEOWNERS +0 -1
  30. data/.github/workflows/pipeline.yml +0 -36
  31. data/.rspec +0 -3
  32. data/.tool-versions +0 -1
  33. data/Appraisals +0 -19
  34. data/CHANGELOG.md +0 -149
  35. data/gemfiles/rails_5.gemfile +0 -18
  36. data/gemfiles/rails_6.gemfile +0 -18
  37. data/gemfiles/rails_7.gemfile +0 -18
  38. data/lib/exception_handling/escalate_callback.rb +0 -19
  39. data/lib/exception_handling/logging_methods.rb +0 -27
  40. data/spec/rake_test_warning_false.rb +0 -20
  41. data/spec/unit/exception_handling/escalate_callback_spec.rb +0 -81
  42. data/spec/unit/exception_handling/exception_catalog_spec.rb +0 -85
  43. data/spec/unit/exception_handling/exception_description_spec.rb +0 -82
  44. data/spec/unit/exception_handling/logging_methods_spec.rb +0 -38
  45. data/spec/unit/exception_handling/methods_spec.rb +0 -105
  46. data/spec/unit/exception_handling/sensu_spec.rb +0 -51
  47. data/spec/unit/exception_handling_spec.rb +0 -1465
  48. /data/{spec → test}/helpers/controller_helpers.rb +0 -0
@@ -3,7 +3,7 @@
3
3
  module ExceptionHandling
4
4
  class ExceptionInfo
5
5
 
6
- ENVIRONMENT_ALLOWLIST = [
6
+ ENVIRONMENT_WHITELIST = [
7
7
  /^HTTP_/,
8
8
  /^QUERY_/,
9
9
  /^REQUEST_/,
@@ -46,20 +46,16 @@ module ExceptionHandling
46
46
  EOS
47
47
 
48
48
  SECTIONS = [:request, :session, :environment, :backtrace, :event_response].freeze
49
- HONEYBADGER_CONTEXT_SECTIONS = [:timestamp, :error_class, :exception_context, :server, :scm_revision, :notes,
50
- :user_details, :request, :session, :environment, :backtrace, :event_response, :log_context].freeze
49
+ HONEYBADGER_CONTEXT_SECTIONS = [:timestamp, :error_class, :exception_context, :server, :scm_revision, :notes, :user_details, :request, :session, :environment, :backtrace, :event_response].freeze
51
50
 
52
- attr_reader :exception, :controller, :exception_context, :timestamp, :honeybadger_tags
51
+ attr_reader :exception, :controller, :exception_context, :timestamp
53
52
 
54
- def initialize(exception, exception_context, timestamp, controller: nil, data_callback: nil, log_context: nil)
53
+ def initialize(exception, exception_context, timestamp, controller = nil, data_callback = nil)
55
54
  @exception = exception
56
55
  @exception_context = exception_context
57
56
  @timestamp = timestamp
58
57
  @controller = controller || controller_from_context(exception_context)
59
58
  @data_callback = data_callback
60
- # merge into the surrounding context just like ContextualLogger does when logging
61
- @merged_log_context = ExceptionHandling.logger.current_context_for_thread.deep_merge(log_context || {})
62
- @honeybadger_tags = Array(@merged_log_context[:honeybadger_tags] || [])
63
59
  end
64
60
 
65
61
  def data
@@ -83,10 +79,9 @@ module ExceptionHandling
83
79
  end
84
80
 
85
81
  def controller_name
86
- @controller_name ||= (
87
- @merged_log_context[:honeybadger_grouping] ||
88
- (@controller && @controller.request.parameters.with_indifferent_access[:controller])
89
- ).to_s
82
+ @controller_name ||= if @controller
83
+ @controller.request.parameters.with_indifferent_access[:controller]
84
+ end.to_s
90
85
  end
91
86
 
92
87
  private
@@ -181,7 +176,7 @@ module ExceptionHandling
181
176
 
182
177
  def clean_environment(env)
183
178
  Hash[ env.map do |k, v|
184
- [k, v] if !"#{k}: #{v}".in?(ENVIRONMENT_OMIT) && ENVIRONMENT_ALLOWLIST.any? { |regex| k =~ regex }
179
+ [k, v] if !"#{k}: #{v}".in?(ENVIRONMENT_OMIT) && ENVIRONMENT_WHITELIST.any? { |regex| k =~ regex }
185
180
  end.compact ]
186
181
  end
187
182
 
@@ -272,13 +267,14 @@ module ExceptionHandling
272
267
  data = enhanced_data.dup
273
268
  data[:server] = ExceptionHandling.server_name
274
269
  data[:exception_context] = deep_clean_hash(@exception_context) if @exception_context.present?
275
- data[:log_context] = @merged_log_context
276
270
  unstringify_sections(data)
277
- HONEYBADGER_CONTEXT_SECTIONS.each_with_object({}) do |section, context|
271
+ context_data = HONEYBADGER_CONTEXT_SECTIONS.reduce({}) do |context, section|
278
272
  if data[section].present?
279
273
  context[section] = data[section]
280
274
  end
275
+ context
281
276
  end
277
+ context_data
282
278
  end
283
279
  end
284
280
  end
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ExceptionHandling
4
+ module HoneybadgerCallbacks
5
+ class << self
6
+ def register_callbacks
7
+ if ExceptionHandling.honeybadger_defined?
8
+ Honeybadger.local_variable_filter(&method(:local_variable_filter))
9
+ end
10
+ end
11
+
12
+ private
13
+
14
+ def inspect_object(object, filter_keys)
15
+ inspection_output = object.inspect
16
+
17
+ if contains_filter_key?(filter_keys, inspection_output)
18
+ filtered_object(object)
19
+ else
20
+ inspection_output
21
+ end
22
+ rescue => ex
23
+ details = if object.respond_to?(:to_pk)
24
+ " @pk=#{object.to_pk}"
25
+ elsif object.respond_to?(:id)
26
+ " @id=#{object.id}"
27
+ end
28
+
29
+ "#<#{object.class.name}#{details} [error '#{ex.class.name}: #{ex.message}' while calling #inspect]>"
30
+ end
31
+
32
+ def local_variable_filter(_symbol, object, filter_keys)
33
+ case object
34
+ # Honeybadger will filter these data types for us
35
+ when String, Hash, Array, Set, Numeric, TrueClass, FalseClass, NilClass
36
+ object
37
+ else # handle other Ruby objects, intended for POROs
38
+ inspect_object(object, filter_keys)
39
+ end
40
+ end
41
+
42
+ def contains_filter_key?(filter_keys, string)
43
+ filter_keys._?.any? { |key| string.include?(key) }
44
+ end
45
+
46
+ def filtered_object(object)
47
+ # make the output look similar to inspect
48
+ # use [FILTERED], just like honeybadger does
49
+ if object.respond_to?(:to_pk)
50
+ "#<#{object.class.name} @pk=#{object.to_pk}, [FILTERED]>"
51
+ elsif object.respond_to?(:id)
52
+ "#<#{object.class.name} @id=#{object.id}, [FILTERED]>"
53
+ else
54
+ "#<#{object.class.name} [FILTERED]>"
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
@@ -1,8 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  #
4
- # Test Helper that supports Minitest::Test and Test::Unit
5
- # Used by tests in the consumers of this gem to track exceptions.
4
+ # Used by functional tests to track exceptions.
6
5
  #
7
6
 
8
7
  module LogErrorStub
@@ -1,15 +1,65 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'active_support/concern'
4
- require_relative 'logging_methods'
5
4
 
6
5
  module ExceptionHandling
7
6
  module Methods # included on models and controllers
8
7
  extend ActiveSupport::Concern
9
- include ExceptionHandling::LoggingMethods
10
8
 
11
9
  protected
12
10
 
11
+ def log_error(exception_or_string, exception_context = '')
12
+ controller = self if respond_to?(:request) && respond_to?(:session)
13
+ ExceptionHandling.log_error(exception_or_string, exception_context, controller)
14
+ end
15
+
16
+ def log_error_rack(exception_or_string, exception_context = '', rack_filter = '')
17
+ ExceptionHandling.log_error_rack(exception_or_string, exception_context, rack_filter)
18
+ end
19
+
20
+ def log_warning(message)
21
+ ExceptionHandling.log_warning(message)
22
+ end
23
+
24
+ def log_info(message)
25
+ ExceptionHandling.logger.info(message)
26
+ end
27
+
28
+ def log_debug(message)
29
+ ExceptionHandling.logger.debug(message)
30
+ end
31
+
32
+ def ensure_safe(exception_context = "")
33
+ yield
34
+ rescue => ex
35
+ log_error ex, exception_context
36
+ nil
37
+ end
38
+
39
+ def escalate_error(exception_or_string, email_subject)
40
+ ExceptionHandling.escalate_error(exception_or_string, email_subject)
41
+ end
42
+
43
+ def escalate_warning(message, email_subject)
44
+ ExceptionHandling.escalate_warning(message, email_subject)
45
+ end
46
+
47
+ def ensure_escalation(*args)
48
+ ExceptionHandling.ensure_escalation(*args) do
49
+ yield
50
+ end
51
+ end
52
+
53
+ def alert_warning(*args)
54
+ ExceptionHandling.alert_warning(*args)
55
+ end
56
+
57
+ def ensure_alert(*args)
58
+ ExceptionHandling.ensure_alert(*args) do
59
+ yield
60
+ end
61
+ end
62
+
13
63
  def long_controller_action_timeout
14
64
  if defined?(Rails) && Rails.respond_to?(:env) && Rails.env == 'test'
15
65
  300
@@ -38,10 +88,7 @@ module ExceptionHandling
38
88
  end
39
89
 
40
90
  included do
41
- Deprecation3_0.deprecation_warning('ExceptionHandling::Methods', 'include LoggingMethods; in controllers, set your own around_filter to set logging context')
42
- if respond_to? :around_filter
43
- around_filter :set_current_controller
44
- end
91
+ around_filter :set_current_controller if respond_to? :around_filter
45
92
  end
46
93
 
47
94
  class_methods do
@@ -4,7 +4,7 @@
4
4
 
5
5
  module ExceptionHandling
6
6
  module Testing
7
- class ControllerStubBase
7
+ class ControllerStub
8
8
 
9
9
  class Request
10
10
  attr_accessor :parameters, :protocol, :host, :request_uri, :env, :session_options
@@ -25,7 +25,7 @@ module ExceptionHandling
25
25
  attr_accessor :around_filter_method
26
26
 
27
27
  def around_filter(method)
28
- self.around_filter_method = method
28
+ ControllerStub.around_filter_method = method
29
29
  end
30
30
  end
31
31
 
@@ -44,6 +44,14 @@ module ExceptionHandling
44
44
  end
45
45
  end
46
46
 
47
+ def simulate_around_filter(&block)
48
+ set_current_controller(&block)
49
+ end
50
+
51
+ def controller_name
52
+ "ControllerStub"
53
+ end
54
+
47
55
  def action_name
48
56
  "test_action"
49
57
  end
@@ -51,27 +59,9 @@ module ExceptionHandling
51
59
  def complete_request_uri
52
60
  "#{@request.protocol}#{@request.host}#{@request.request_uri}"
53
61
  end
54
- end
55
-
56
- class LoggingMethodsControllerStub < ControllerStubBase
57
- include ExceptionHandling::LoggingMethods
58
-
59
- def controller_name
60
- "LoggingMethodsControllerStub"
61
- end
62
- end
63
62
 
64
- class MethodsControllerStub < ControllerStubBase
65
63
  include ExceptionHandling::Methods
66
64
  set_long_controller_action_timeout 2
67
-
68
- def simulate_around_filter(&block)
69
- set_current_controller(&block)
70
- end
71
-
72
- def controller_name
73
- "MethodsControllerStub"
74
- end
75
65
  end
76
66
  end
77
67
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ExceptionHandling
4
- VERSION = '2.17.0.pre.tstarck.1'
4
+ VERSION = '3.0.pre.1'
5
5
  end
@@ -1,21 +1,20 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'digest'
4
3
  require 'timeout'
5
4
  require 'active_support'
6
- require 'active_support/core_ext'
5
+ require 'active_support/core_ext/hash'
7
6
  require 'contextual_logger'
8
7
 
9
8
  require 'invoca/utils'
10
9
 
11
- require 'exception_handling/mailer'
12
- require 'exception_handling/sensu'
13
- require 'exception_handling/methods'
14
- require 'exception_handling/log_stub_error'
15
- require 'exception_handling/exception_description'
16
- require 'exception_handling/exception_catalog'
17
- require 'exception_handling/exception_info'
18
- require 'exception_handling/escalate_callback'
10
+ require "exception_handling/mailer"
11
+ require "exception_handling/sensu"
12
+ require "exception_handling/methods"
13
+ require "exception_handling/log_stub_error"
14
+ require "exception_handling/exception_description"
15
+ require "exception_handling/exception_catalog"
16
+ require "exception_handling/exception_info"
17
+ require "exception_handling/honeybadger_callbacks.rb"
19
18
 
20
19
  _ = ActiveSupport::HashWithIndifferentAccess
21
20
 
@@ -30,8 +29,6 @@ module ExceptionHandling # never included
30
29
  AUTHENTICATION_HEADERS = ['HTTP_AUTHORIZATION', 'X-HTTP_AUTHORIZATION', 'X_HTTP_AUTHORIZATION', 'REDIRECT_X_HTTP_AUTHORIZATION'].freeze
31
30
  HONEYBADGER_STATUSES = [:success, :failure, :skipped].freeze
32
31
 
33
- Deprecation3_0 = ActiveSupport::Deprecation.new('3.0', 'exception_handling')
34
-
35
32
  class << self
36
33
 
37
34
  #
@@ -53,28 +50,15 @@ module ExceptionHandling # never included
53
50
  @exception_recipients or raise ArgumentError, "You must assign a value to #{name}.exception_recipients"
54
51
  end
55
52
 
56
- def configured?
57
- !@logger.nil?
58
- end
59
-
60
53
  def logger
61
54
  @logger or raise ArgumentError, "You must assign a value to #{name}.logger"
62
55
  end
63
56
 
64
57
  def logger=(logger)
65
- @logger = if logger.nil? || logger.is_a?(ContextualLogger::LoggerMixin)
66
- logger
67
- else
68
- Deprecation3_0.deprecation_warning('implicit extend with ContextualLogger::LoggerMixin', 'extend your logger instance or include into your logger class first')
69
- logger.extend(ContextualLogger::LoggerMixin)
70
- end
71
- EscalateCallback.register_if_configured!
58
+ @logger = logger.is_a?(ContextualLogger) ? logger : ContextualLogger.new(logger)
72
59
  end
73
60
 
74
- def default_metric_name(exception_data, exception, treat_like_warning, include_prefix: true)
75
- include_prefix and Deprecation3_0.deprecation_warning("the 'expection_handling.' prefix in ExceptionHandling::default_metric_name",
76
- "do not rely on metric names including the 'exception_handling.' prefix.")
77
-
61
+ def default_metric_name(exception_data, exception, treat_like_warning)
78
62
  metric_name = if exception_data['metric_name']
79
63
  exception_data['metric_name']
80
64
  elsif exception.is_a?(ExceptionHandling::Warning)
@@ -86,7 +70,7 @@ module ExceptionHandling # never included
86
70
  "exception"
87
71
  end
88
72
 
89
- "#{'exception_handling.' if include_prefix}#{metric_name}"
73
+ "exception_handling.#{metric_name}"
90
74
  end
91
75
 
92
76
  def default_honeybadger_metric_name(honeybadger_status)
@@ -110,12 +94,10 @@ module ExceptionHandling # never included
110
94
  attr_accessor :sensu_host
111
95
  attr_accessor :sensu_port
112
96
  attr_accessor :sensu_prefix
113
- attr_reader :honeybadger_log_context_tags
114
97
 
115
98
  attr_reader :filter_list_filename
116
99
  attr_reader :eventmachine_safe
117
100
  attr_reader :eventmachine_synchrony
118
- attr_reader :honeybadger_auto_tagger
119
101
 
120
102
  @filter_list_filename = "./config/exception_filters.yml"
121
103
  @email_environment = ""
@@ -156,30 +138,6 @@ module ExceptionHandling # never included
156
138
  @exception_catalog ||= ExceptionCatalog.new(@filter_list_filename)
157
139
  end
158
140
 
159
- # rubocop:disable Style/TrivialAccessors
160
- # @param value [Proc|nil] Proc that accepts 1 parameter that will be the exception object or nil to disable the auto-tagger.
161
- # The proc is always expected to return an array of strings. The array can be empty.
162
- def honeybadger_auto_tagger=(value)
163
- @honeybadger_auto_tagger = value
164
- end
165
- # rubocop:enable Style/TrivialAccessors
166
-
167
- # @param tag_name [String]
168
- # @param path [Array]
169
- def add_honeybadger_tag_from_log_context(tag_name, path:)
170
- tag_name.is_a?(String) or raise ArgumentError, "tag_name must be a String, #{tag_name.inspect}"
171
- path.is_a?(Array) or raise ArgumentError, "path must be an Array, #{path.inspect}"
172
- @honeybadger_log_context_tags ||= {}
173
- if @honeybadger_log_context_tags.key?(tag_name)
174
- log_warning("Overwriting existing tag path for '#{tag_name}' from #{@honeybadger_log_context_tags[tag_name]} to #{path}")
175
- end
176
- @honeybadger_log_context_tags[tag_name] = path
177
- end
178
-
179
- def clear_honeybadger_tags_from_log_context
180
- @honeybadger_log_context_tags = nil
181
- end
182
-
183
141
  #
184
142
  # internal settings (don't set directly)
185
143
  #
@@ -219,18 +177,13 @@ module ExceptionHandling # never included
219
177
  # Called directly by our code, usually from rescue blocks.
220
178
  # Writes to log file and may send to honeybadger
221
179
  #
222
- # TODO: the **log_context means we can never have context named treat_like_warning. In general, keyword args will be conflated with log_context.
223
- # Ideally we'd separate to log_context from the other keywords so they don't interfere in any way. Or have no keyword args.
224
- #
225
180
  # Functional Test Operation:
226
181
  # Calls into handle_stub_log_error and returns. no log file. no honeybadger
227
182
  #
228
- def log_error(exception_or_string, exception_context = '', controller = nil, treat_like_warning: false, **log_context, &data_callback)
183
+ def log_error(exception_or_string, exception_context = '', treat_like_warning: false, **log_context, &data_callback)
229
184
  ex = make_exception(exception_or_string)
230
185
  timestamp = set_log_error_timestamp
231
- exception_info = ExceptionInfo.new(ex, exception_context, timestamp,
232
- controller: controller || current_controller, data_callback: data_callback,
233
- log_context: log_context)
186
+ exception_info = ExceptionInfo.new(ex, exception_context, timestamp, current_controller, data_callback)
234
187
 
235
188
  if stub_handler
236
189
  stub_handler.handle_stub_log_error(exception_info.data)
@@ -257,13 +210,7 @@ module ExceptionHandling # never included
257
210
  #
258
211
  def write_exception_to_log(ex, exception_context, timestamp, log_context = {})
259
212
  ActiveSupport::Deprecation.silence do
260
- log_message = "#{exception_context}\n#{ex.class}: (#{encode_utf8(ex.message.to_s)}):\n " + clean_backtrace(ex).join("\n ") + "\n\n"
261
-
262
- if ex.is_a?(Warning)
263
- ExceptionHandling.logger.warn("\nExceptionHandlingWarning (Warning:#{timestamp}) #{log_message}", **log_context)
264
- else
265
- ExceptionHandling.logger.fatal("\nExceptionHandlingError (Error:#{timestamp}) #{log_message}", **log_context)
266
- end
213
+ ExceptionHandling.logger.fatal("\nExceptionHandlingError (Error:#{timestamp}) #{ex.class} #{exception_context} (#{encode_utf8(ex.message.to_s)}):\n " + clean_backtrace(ex).join("\n ") + "\n\n", log_context)
267
214
  end
268
215
  end
269
216
 
@@ -296,16 +243,11 @@ module ExceptionHandling # never included
296
243
  def send_exception_to_honeybadger(exception_info)
297
244
  exception = exception_info.exception
298
245
  exception_description = exception_info.exception_description
299
-
300
- # Note: Both commas and spaces are treated as delimiters for the :tags string. Space-delimiters are not officially documented.
301
- # https://github.com/honeybadger-io/honeybadger-ruby/pull/422
302
- tags = tags_for_honeybadger(exception_info).join(' ')
303
246
  response = Honeybadger.notify(error_class: exception_description ? exception_description.filter_name : exception.class.name,
304
247
  error_message: exception.message.to_s,
305
248
  exception: exception,
306
249
  context: exception_info.honeybadger_context_data,
307
- controller: exception_info.controller_name,
308
- tags: tags)
250
+ controller: exception_info.controller_name)
309
251
  response ? :success : :failure
310
252
  rescue Exception => ex
311
253
  warn("ExceptionHandling.send_exception_to_honeybadger rescued exception while logging #{exception_info.exception_context}:\n#{exception.class}: #{exception.message}:\n#{ex.class}: #{ex.message}\n#{ex.backtrace.join("\n")}")
@@ -323,41 +265,38 @@ module ExceptionHandling # never included
323
265
  #
324
266
  # Expects passed in hash to only include keys which be directly set on the Honeybadger config
325
267
  #
326
- def enable_honeybadger(**config)
268
+ def enable_honeybadger(config = {})
327
269
  Bundler.require(:honeybadger)
270
+ HoneybadgerCallbacks.register_callbacks
328
271
  Honeybadger.configure do |config_klass|
329
272
  config.each do |k, v|
330
- if k == :before_notify
331
- config_klass.send(k, v)
332
- else
333
- config_klass.send(:"#{k}=", v)
334
- end
273
+ config_klass.send(:"#{k}=", v)
335
274
  end
336
275
  end
337
276
  end
338
277
 
339
- def log_warning(message, **log_context)
278
+ def log_warning(message, log_context = {})
340
279
  warning = Warning.new(message)
341
280
  warning.set_backtrace([])
342
281
  log_error(warning, **log_context)
343
282
  end
344
283
 
345
- def log_info(message, **log_context)
346
- ExceptionHandling.logger.info(message, **log_context)
284
+ def log_info(message, log_context = {})
285
+ ExceptionHandling.logger.info(message, log_context)
347
286
  end
348
287
 
349
- def log_debug(message, **log_context)
350
- ExceptionHandling.logger.debug(message, **log_context)
288
+ def log_debug(message, log_context = {})
289
+ ExceptionHandling.logger.debug(message, log_context)
351
290
  end
352
291
 
353
- def ensure_safe(exception_context = "", **log_context)
292
+ def ensure_safe(exception_context = "", log_context = {})
354
293
  yield
355
294
  rescue => ex
356
295
  log_error(ex, exception_context, **log_context)
357
296
  nil
358
297
  end
359
298
 
360
- def ensure_completely_safe(exception_context = "", **log_context)
299
+ def ensure_completely_safe(exception_context = "", log_context = {})
361
300
  yield
362
301
  rescue SystemExit, SystemStackError, NoMemoryError, SecurityError, SignalException
363
302
  raise
@@ -372,29 +311,26 @@ module ExceptionHandling # never included
372
311
  escalate(email_subject, ex, last_exception_timestamp, production_support_recipients)
373
312
  end
374
313
 
375
- def escalate_error(exception_or_string, email_subject, custom_recipients = nil, **log_context)
314
+ def escalate_error(exception_or_string, email_subject, custom_recipients = nil, log_context = {})
376
315
  ex = make_exception(exception_or_string)
377
316
  log_error(ex, **log_context)
378
317
  escalate(email_subject, ex, last_exception_timestamp, custom_recipients)
379
318
  end
380
319
 
381
- def escalate_warning(message, email_subject, custom_recipients = nil, **log_context)
320
+ def escalate_warning(message, email_subject, custom_recipients = nil, log_context = {})
382
321
  ex = Warning.new(message)
383
322
  log_error(ex, **log_context)
384
323
  escalate(email_subject, ex, last_exception_timestamp, custom_recipients)
385
324
  end
386
325
 
387
- def ensure_escalation(email_subject, custom_recipients = nil, **log_context)
326
+ def ensure_escalation(email_subject, custom_recipients = nil, log_context = {})
388
327
  yield
389
328
  rescue => ex
390
- escalate_error(ex, email_subject, custom_recipients, **log_context)
329
+ escalate_error(ex, email_subject, custom_recipients, log_context)
391
330
  nil
392
331
  end
393
332
 
394
- deprecate :escalate_to_production_support, :escalate_error, :escalate_warning, :ensure_escalation,
395
- deprecator: ActiveSupport::Deprecation.new('3.0', 'ExceptionHandling')
396
-
397
- def alert_warning(exception_or_string, alert_name, exception_context, **log_context)
333
+ def alert_warning(exception_or_string, alert_name, exception_context, log_context)
398
334
  ex = make_exception(exception_or_string)
399
335
  log_error(ex, exception_context, **log_context)
400
336
  begin
@@ -404,10 +340,10 @@ module ExceptionHandling # never included
404
340
  end
405
341
  end
406
342
 
407
- def ensure_alert(alert_name, exception_context, **log_context)
343
+ def ensure_alert(alert_name, exception_context, log_context = {})
408
344
  yield
409
345
  rescue => ex
410
- alert_warning(ex, alert_name, exception_context, **log_context)
346
+ alert_warning(ex, alert_name, exception_context, log_context)
411
347
  nil
412
348
  end
413
349
 
@@ -424,7 +360,7 @@ module ExceptionHandling # never included
424
360
  result
425
361
  end
426
362
 
427
- def log_periodically(exception_key, interval, message, **log_context)
363
+ def log_periodically(exception_key, interval, message, log_context = {})
428
364
  self.periodic_exception_intervals ||= {}
429
365
  last_logged = self.periodic_exception_intervals[exception_key]
430
366
  if !last_logged || ((last_logged + interval) < Time.now)
@@ -461,41 +397,6 @@ module ExceptionHandling # never included
461
397
 
462
398
  private
463
399
 
464
- # @param exception_info [ExceptionInfo]
465
- #
466
- # @return [Array<String>]
467
- def tags_for_honeybadger(exception_info)
468
- (
469
- honeybadger_auto_tags(exception_info.exception) +
470
- exception_info.honeybadger_tags +
471
- honeybadger_tags_from_log_context(exception_info.honeybadger_context_data)
472
- ).uniq
473
- end
474
-
475
- # @param exception [Exception]
476
- #
477
- # @return [Array<String>]
478
- def honeybadger_auto_tags(exception)
479
- @honeybadger_auto_tagger&.call(exception) || []
480
- rescue => ex
481
- traces = ex.backtrace.join("\n")
482
- message = "Unable to execute honeybadger_auto_tags callback. #{ExceptionHandling.encode_utf8(ex.message.to_s)} #{traces}\n"
483
- ExceptionHandling.log_info(message)
484
- []
485
- end
486
-
487
- def honeybadger_tags_from_log_context(honeybadger_context_data)
488
- if @honeybadger_log_context_tags
489
- @honeybadger_log_context_tags.map do |tag_name, tag_path|
490
- if (value_from_log_context = honeybadger_context_data.dig(:log_context, *tag_path))
491
- "#{tag_name}:#{value_from_log_context}"
492
- end
493
- end.compact
494
- else
495
- []
496
- end
497
- end
498
-
499
400
  def execute_custom_log_error_callback(exception_data, exception, treat_like_warning, external_notification_results)
500
401
  if ExceptionHandling.post_log_error_hook
501
402
  honeybadger_status = external_notification_results[:honeybadger_status] || :skipped
@@ -562,6 +463,4 @@ module ExceptionHandling # never included
562
463
  end
563
464
  end
564
465
  end
565
-
566
- EscalateCallback.register_if_configured!
567
466
  end
@@ -0,0 +1,3 @@
1
+ #!/bin/sh -x
2
+
3
+ bundle install --path vendor/bundle
@@ -7,7 +7,7 @@ module ExceptionHelpers
7
7
 
8
8
  def exception_with_nil_message
9
9
  exception_with_nil_message = RuntimeError.new(nil)
10
- allow(exception_with_nil_message).to receive(:message).and_return(nil)
10
+ stub(exception_with_nil_message).message { nil }
11
11
  exception_with_nil_message
12
12
  end
13
13
 
@@ -15,6 +15,6 @@ module ExceptionHelpers
15
15
 
16
16
  def capture_notifications
17
17
  @sent_notifications = []
18
- allow(ExceptionHandling).to receive(:send_exception_to_honeybadger).with(any_args) { |exception_info| @sent_notifications << exception_info }
18
+ stub(ExceptionHandling).send_exception_to_honeybadger(anything) { |exception_info| @sent_notifications << exception_info }
19
19
  end
20
20
  end