escalate 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: ca403c35fe8123ebf15d068d392789e5de418f71
4
- data.tar.gz: df6eb4d755258ce4e6d3617ca88075266e591acc
2
+ SHA256:
3
+ metadata.gz: 367073142399930c67886a1890af1e684d767a11c62d3719fd95ecd392a4c47d
4
+ data.tar.gz: 368728d4e4db7d3e466571c563902e096093310685ffffc64c1906b05d95338e
5
5
  SHA512:
6
- metadata.gz: aae531b8f6fc1f8bb4e52a2cbf1ff613fd74f19298ca18aca77936f6e44b741c9ce42b02817bcfb755379d95c6e577342b1a17af0a387e66a00348baf96a3703
7
- data.tar.gz: 2d4c26aad91e60c1c2b192b66d6f332db6a858b7f06588788f5b166d41912a8daa27cac39d166ac3cea7e770417037062add542bf36f4429a8c0cc8f0ad74a7b
6
+ metadata.gz: 59605b0ed9a30982a6e6dc92d37c20578b4b52c643361a8b6e7ac2876579ade371c0b528f156de8da92502f7002d66f515c467f8fe5e4a5038580d506f174d08
7
+ data.tar.gz: 0a24440c7988110d5cacc07bd6ec262074de501938c4076e29bea9607ee38d4d6c19f424086f81fd09ef9266e65f65a9f39b6f9ca36018fcbe9f9688041d820e
data/CHANGELOG.md CHANGED
@@ -4,10 +4,17 @@ All notable changes to this project will be documented in this file.
4
4
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
5
5
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
6
 
7
+ ## [0.2.0] - 2021-03-02
8
+ ### Added
9
+ - Added support for `on_escalate(log_first: false)`. The `escalate` gem will log first before
10
+ escalating if either of these is true: there are no `on_escalate` blocks registered, or
11
+ there are some and at least one of them passed `log_first: false`.
12
+
7
13
  ## [0.1.0] - 2021-02-03
8
14
  ### Added
9
15
  - Added `Escalate.mixin` interface for mixing in `Escalate` with your module for easy escalation of rescued exceptions
10
16
  - Added `escalate` method for escalating rescued exceptions with default behavior of logging to `STDERR`
11
17
  - Added `Escalate.on_escalate` for registering escalation callbacks like `Honeybadger` or `Sentry`
12
18
 
19
+ [0.2.0]: https://github.com/Invoca/escalate/compare/v0.1.0...v0.2.0
13
20
  [0.1.0]: https://github.com/Invoca/escalate/releases/tag/v0.1.0
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- escalate (0.1.0)
4
+ escalate (0.2.0)
5
5
  activesupport
6
6
 
7
7
  GEM
@@ -49,6 +49,7 @@ GEM
49
49
  thread_safe (~> 0.1)
50
50
 
51
51
  PLATFORMS
52
+ ruby
52
53
  x86_64-darwin-19
53
54
 
54
55
  DEPENDENCIES
data/README.md CHANGED
@@ -58,8 +58,44 @@ end
58
58
  When `SomeGem.escalate` above is triggered, it will use the logger returned by `SomeGem.logger` or
59
59
  default to a `STDERR` logger and do the following:
60
60
 
61
- 1. Log an error containing the exception and any additional information about the current environment that is specified
62
- 2. Trigger any `escalation_callbacks` configured on the `Escalate` gem
61
+ 1. [optional] Log an error containing the exception, location_message, and context hash
62
+ 2. Trigger any `on_escalate_callbacks` configured on the `Escalate` gem
63
+
64
+ Step (1) is optional. It will happen if either of these is true:
65
+ - by default if no `on_escalate_callbacks` have been registered; or
66
+ - if any of the `on_escalate_callbacks` was registered with `on_escalate(log_first: true)`.
67
+
68
+ ### Registering an Escalate Callback
69
+
70
+ If you are using an error reporting service, you can register an `on_escalate` callback to escalate exceptions.
71
+ You have the option to handle logging yourself, or to let `escalate` log first, before calling your callback.
72
+
73
+ #### Leave the Logging to the Escalate Gem
74
+ Here is an example that uses the default `log_first: true` so that logging is handled by the `Escalate` gem first:
75
+ ```
76
+ Escalate.on_escalate do |exception, location_message, **context|
77
+ # send exception, location_message, **context to the error reporting service here
78
+ end
79
+ ```
80
+
81
+ #### Callback Uniqueness
82
+ Each callback may be named with the `name:` keyword argument.
83
+ If a callback with the same name has been registered before, it will be overwritten with the new one.
84
+ ```
85
+ Escalate.on_escalate(name: 'abc gem') do |exception, location_message, **context|
86
+ # send exception, location_message, **context to the error reporting service here
87
+ end
88
+ ```
89
+ If not given, the `name:` defaults to the `.source_location` property of the passed-in block.
90
+
91
+ #### Handle the Logging in the `on_escalate` Callback
92
+ Here is an example that handles logging itself with `log_first: false`:
93
+ ```
94
+ Escalate.on_escalate(log_first: false) do |exception, location_message, **context|
95
+ # log here first
96
+ # send exception, location_message, **context to the error reporting service here
97
+ end
98
+ ```
63
99
  ## Development
64
100
 
65
101
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
data/lib/escalate.rb CHANGED
@@ -9,37 +9,46 @@ require_relative "escalate/mixin"
9
9
  module Escalate
10
10
  class Error < StandardError; end
11
11
 
12
+ LOG_FIRST_INSTANCE_VARIABLE = :@_escalate_log_first
13
+
14
+ @on_escalate_callbacks = {}
15
+
12
16
  class << self
17
+ attr_reader :on_escalate_callbacks
18
+
13
19
  # Logs and escalated an exception
14
20
  #
15
21
  # @param [Exception] exception
16
- # The exception that was raised and needs to be escalated
22
+ # The exception that was rescued and needs to be escalated
17
23
  #
18
- # @param [String] message
19
- # An additional message about what was happening at the time of the exception
24
+ # @param [String] location_message
25
+ # An additional message giving an indication of where in the code this exception was rescued
20
26
  #
21
27
  # @param [Logger] logger
22
28
  # The logger object to use when logging the exception
23
29
  #
24
30
  # @param [Hash] context
25
31
  # Any additional context to be tied to the escalation
26
- def escalate(exception, message, logger, **context)
32
+ def escalate(exception, location_message, logger, **context)
27
33
  ensure_failsafe("Exception rescued while escalating #{exception.inspect}") do
28
- error_message = <<~EOS
29
- [Escalate] #{message} (#{context.inspect})
34
+ if on_escalate_callbacks.none? || on_escalate_callbacks.values.any? { |block| block.instance_variable_get(LOG_FIRST_INSTANCE_VARIABLE) }
35
+ logger_allows_added_context?(logger) or context_string = " (#{context.inspect})"
36
+ error_message = <<~EOS
37
+ [Escalate] #{location_message}#{context_string}
30
38
  #{exception.class.name}: #{exception.message}
31
39
  #{exception.backtrace.join("\n")}
32
- EOS
40
+ EOS
33
41
 
34
- if logger_allows_added_context?(logger)
35
- logger.error(error_message, **context)
36
- else
37
- logger.error(error_message)
42
+ if context_string
43
+ logger.error(error_message)
44
+ else
45
+ logger.error(error_message, **context)
46
+ end
38
47
  end
39
48
 
40
- on_escalate_blocks.each do |block|
49
+ on_escalate_callbacks.values.each do |block|
41
50
  ensure_failsafe("Exception rescued while escalating #{exception.inspect} to #{block.inspect}") do
42
- block.call(exception, message, **context)
51
+ block.call(exception, location_message, **context)
43
52
  end
44
53
  end
45
54
  end
@@ -63,8 +72,8 @@ module Escalate
63
72
 
64
73
  attr_accessor :escalate_logger_block
65
74
 
66
- def escalate(exception, message, **context)
67
- Escalate.escalate(exception, message, escalate_logger, **context)
75
+ def escalate(exception, location_message, **context)
76
+ Escalate.escalate(exception, location_message, escalate_logger, **context)
68
77
  end
69
78
 
70
79
  private
@@ -79,10 +88,21 @@ module Escalate
79
88
  end
80
89
  end
81
90
 
82
- # Registers an escalation callback to be executed when `escalate`
83
- # is invoked.
84
- def on_escalate(&block)
85
- on_escalate_blocks.add(block)
91
+ # Registers an escalation callback to be executed when `escalate` is invoked.
92
+ #
93
+ # @param [boolean] log_first: true
94
+ # whether escalate should log first before escalating, or leave the logging to the escalate block
95
+ # @param [string | Array] name:
96
+ # unique name for this callback block
97
+ # any previously-registered block with the same name will be discarded
98
+ # if not provided, name defaults to `block.source_location`
99
+ def on_escalate(log_first: true, name: nil, &block)
100
+ block.instance_variable_set(LOG_FIRST_INSTANCE_VARIABLE, log_first)
101
+ on_escalate_callbacks[name || block.source_location] = block
102
+ end
103
+
104
+ def clear_on_escalate_callbacks
105
+ on_escalate_callbacks.clear
86
106
  end
87
107
 
88
108
  private
@@ -97,9 +117,5 @@ module Escalate
97
117
  defined?(ContextualLogger::LoggerMixin) &&
98
118
  logger.is_a?(ContextualLogger::LoggerMixin)
99
119
  end
100
-
101
- def on_escalate_blocks
102
- @on_escalate_blocks ||= Set.new
103
- end
104
120
  end
105
121
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Escalate
4
- VERSION = "0.1.0"
4
+ VERSION = "0.2.0"
5
5
  end
metadata CHANGED
@@ -1,15 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: escalate
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Invoca Development
8
8
  - Octothorp
9
- autorequire:
9
+ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2021-02-03 00:00:00.000000000 Z
12
+ date: 2021-03-02 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activesupport
@@ -56,7 +56,7 @@ metadata:
56
56
  allowed_push_host: https://rubygems.org
57
57
  homepage_uri: https://github.com/invoca/escalate
58
58
  changelog_uri: https://github.com/invoca/escalate/blob/main/CHANGELOG.md
59
- post_install_message:
59
+ post_install_message:
60
60
  rdoc_options: []
61
61
  require_paths:
62
62
  - lib
@@ -71,9 +71,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
71
71
  - !ruby/object:Gem::Version
72
72
  version: '0'
73
73
  requirements: []
74
- rubyforge_project:
75
- rubygems_version: 2.6.13
76
- signing_key:
74
+ rubygems_version: 3.1.2
75
+ signing_key:
77
76
  specification_version: 4
78
77
  summary: A simple and lightweight gem to escalate rescued exceptions.
79
78
  test_files: []