escalate 0.2.0 → 0.3.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 367073142399930c67886a1890af1e684d767a11c62d3719fd95ecd392a4c47d
4
- data.tar.gz: 368728d4e4db7d3e466571c563902e096093310685ffffc64c1906b05d95338e
3
+ metadata.gz: 9844b8aaae39fe3b2e23417e7b39e1ec59ff8896e5a6f8be4e3737c3ccf8ce02
4
+ data.tar.gz: 7e03db14d0da2ec0e6458cd03a9da89cf949fce7d2c0a34bad65b69b7ede2409
5
5
  SHA512:
6
- metadata.gz: 59605b0ed9a30982a6e6dc92d37c20578b4b52c643361a8b6e7ac2876579ade371c0b528f156de8da92502f7002d66f515c467f8fe5e4a5038580d506f174d08
7
- data.tar.gz: 0a24440c7988110d5cacc07bd6ec262074de501938c4076e29bea9607ee38d4d6c19f424086f81fd09ef9266e65f65a9f39b6f9ca36018fcbe9f9688041d820e
6
+ metadata.gz: e8eab0d9486440921db00178fa7560779976ed9e132377ca1dacea9960a9847f6eed01f964945f88719ef26583789b6bf1dad83f7dbcaef8c3625e83e8825c15
7
+ data.tar.gz: fa039e7c5c2c3e0c48e50840ba0831eb0f7a87d2902690b3740304f2b36b8aca91df8233c885c6e60ef9bd26fd0b4929604040082adefbdcbf0cbb14287a42ca
data/CHANGELOG.md CHANGED
@@ -4,6 +4,10 @@ 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.3.0] - 2021-03-05
8
+ ### Added
9
+ - Added `rescue_and_escalate`.
10
+
7
11
  ## [0.2.0] - 2021-03-02
8
12
  ### Added
9
13
  - Added support for `on_escalate(log_first: false)`. The `escalate` gem will log first before
@@ -16,5 +20,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
16
20
  - Added `escalate` method for escalating rescued exceptions with default behavior of logging to `STDERR`
17
21
  - Added `Escalate.on_escalate` for registering escalation callbacks like `Honeybadger` or `Sentry`
18
22
 
23
+ [0.3.0]: https://github.com/Invoca/escalate/compare/v0.2.0...v0.3.0
19
24
  [0.2.0]: https://github.com/Invoca/escalate/compare/v0.1.0...v0.2.0
20
25
  [0.1.0]: https://github.com/Invoca/escalate/releases/tag/v0.1.0
data/Gemfile.lock CHANGED
@@ -1,8 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- escalate (0.2.0)
5
- activesupport
4
+ escalate (0.3.0)
6
5
 
7
6
  GEM
8
7
  remote: https://rubygems.org/
data/README.md CHANGED
@@ -34,6 +34,7 @@ module SomeGem
34
34
  end
35
35
  ```
36
36
 
37
+ #### Using .escalate
37
38
  This will expose the `Escalate#escalate` method within your gem to be used instead
38
39
  of using `logger.error`.
39
40
 
@@ -46,14 +47,23 @@ module SomeGem
46
47
  end
47
48
 
48
49
  class SomeClass
49
- def something_dangerous
50
- # ...
51
- rescue => ex
52
- SomeGem.escalate(ex, "I was doing something dangerous and an exception was raised")
50
+ def something_dangerous(key)
51
+ # code here...
52
+ rescue => exception
53
+ SomeGem.escalate(exception,
54
+ "Exception raised in SomeGem::SomeClass#something_dangerous",
55
+ context: { key: key })
53
56
  end
54
57
  end
55
58
  end
56
59
  ```
60
+ The following arguments are supported by `.escalate`:
61
+
62
+ | argument | default | type | description |
63
+ |------------|---|----|-----|
64
+ | `exception` | | `Exception` | The exception to escalate. |
65
+ | `location_message` | | `String` | A message providing information about where and why this exception is being escalated. |
66
+ | `context:` | `{}` | `Hash` | An optional hash of context. This will be logged with the exception. |
57
67
 
58
68
  When `SomeGem.escalate` above is triggered, it will use the logger returned by `SomeGem.logger` or
59
69
  default to a `STDERR` logger and do the following:
@@ -65,10 +75,42 @@ Step (1) is optional. It will happen if either of these is true:
65
75
  - by default if no `on_escalate_callbacks` have been registered; or
66
76
  - if any of the `on_escalate_callbacks` was registered with `on_escalate(log_first: true)`.
67
77
 
78
+ #### Using .rescue_and_escalate
79
+ The above pattern of `rescue` with `escalate` is very common, so a single method is provided to do both.
80
+ This is equivalent to the code above:
81
+ ```
82
+ class SomeClass
83
+ def something_dangerous(key)
84
+ SomeGem.rescue_and_escalate("Exception raised in SomeGem::SomeClass#something_dangerous",
85
+ context: { key: key }) do
86
+ # code here...
87
+ end
88
+ end
89
+ end
90
+ ```
91
+ The following arguments are supported by `.rescue_and_escalate`:
92
+
93
+ | argument | default | type | description |
94
+ |-------------|---|----|-----|
95
+ | `location_message` | _required_ | `String` | A message providing information about where and why this exception is being escalated. |
96
+ | `context:` | `{}` | `Hash` | An optional hash of context. This will be logged with the exception. |
97
+ | `exceptions:` | `StandardError` | `Class` or `Array(Class)` | The `Class` or `Array(Class)` to rescue. `Class` must be `Exception` or a sub-class. |
98
+ | `pass_through_exceptions:` | `[SystemExit, SystemStackError, NoMemoryError, SecurityError, SignalException]` | `Class` or `Array(Class)` | The `Class` or `Array(Class)` to pass through without rescuing. `Class` must be `Exception`, or a sub-class. These take precedence over `exceptions:`.|
99
+
100
+ ----------------------------
101
+
68
102
  ### Registering an Escalate Callback
69
103
 
70
104
  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.
105
+ You have the option to handle logging yourself, or to let `escalate` log first, before yielding to callbacks.
106
+
107
+ The following arguments are supported by `.on_escalate`:
108
+
109
+ | argument | default | type | description |
110
+ |-------------|---|----|-----|
111
+ | `name:` | `block.source_location` | `String` or `Array` | Globally unique name for this callback. |
112
+ | `log_first:` | `true` | `Boolean` | Whether `escalate` should log the error first. `false` means the block will take care of this. |
113
+ | `&block` | _required_ | `Proc` | The callback block to yield to from `escalate`. |
72
114
 
73
115
  #### Leave the Logging to the Escalate Gem
74
116
  Here is an example that uses the default `log_first: true` so that logging is handled by the `Escalate` gem first:
data/escalate.gemspec CHANGED
@@ -26,6 +26,4 @@ Gem::Specification.new do |spec|
26
26
  end
27
27
  spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
28
28
  spec.require_paths = ["lib"]
29
-
30
- spec.add_dependency "activesupport"
31
29
  end
data/lib/escalate.rb CHANGED
@@ -11,6 +11,9 @@ module Escalate
11
11
 
12
12
  LOG_FIRST_INSTANCE_VARIABLE = :@_escalate_log_first
13
13
 
14
+ DEFAULT_RESCUE_EXCEPTIONS = [StandardError].freeze
15
+ DEFAULT_PASS_THROUGH_EXCEPTIONS = [SystemExit, SystemStackError, NoMemoryError, SecurityError, SignalException].freeze
16
+
14
17
  @on_escalate_callbacks = {}
15
18
 
16
19
  class << self
@@ -29,7 +32,7 @@ module Escalate
29
32
  #
30
33
  # @param [Hash] context
31
34
  # Any additional context to be tied to the escalation
32
- def escalate(exception, location_message, logger, **context)
35
+ def escalate(exception, location_message, logger, context: {})
33
36
  ensure_failsafe("Exception rescued while escalating #{exception.inspect}") do
34
37
  if on_escalate_callbacks.none? || on_escalate_callbacks.values.any? { |block| block.instance_variable_get(LOG_FIRST_INSTANCE_VARIABLE) }
35
38
  logger_allows_added_context?(logger) or context_string = " (#{context.inspect})"
@@ -72,8 +75,21 @@ module Escalate
72
75
 
73
76
  attr_accessor :escalate_logger_block
74
77
 
75
- def escalate(exception, location_message, **context)
76
- Escalate.escalate(exception, location_message, escalate_logger, **context)
78
+ def escalate(exception, location_message, context: {})
79
+ Escalate.escalate(exception, location_message, escalate_logger, context: context)
80
+ end
81
+
82
+ def rescue_and_escalate(location_message, context: {},
83
+ exceptions: DEFAULT_RESCUE_EXCEPTIONS,
84
+ pass_through_exceptions: DEFAULT_PASS_THROUGH_EXCEPTIONS,
85
+ &block)
86
+
87
+ yield
88
+
89
+ rescue *Array(pass_through_exceptions)
90
+ raise
91
+ rescue *Array(exceptions) => exception
92
+ escalate(exception, location_message, context: context)
77
93
  end
78
94
 
79
95
  private
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Escalate
4
- VERSION = "0.2.0"
4
+ VERSION = "0.3.0"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: escalate
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Invoca Development
@@ -9,22 +9,8 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2021-03-02 00:00:00.000000000 Z
13
- dependencies:
14
- - !ruby/object:Gem::Dependency
15
- name: activesupport
16
- requirement: !ruby/object:Gem::Requirement
17
- requirements:
18
- - - ">="
19
- - !ruby/object:Gem::Version
20
- version: '0'
21
- type: :runtime
22
- prerelease: false
23
- version_requirements: !ruby/object:Gem::Requirement
24
- requirements:
25
- - - ">="
26
- - !ruby/object:Gem::Version
27
- version: '0'
12
+ date: 2021-03-05 00:00:00.000000000 Z
13
+ dependencies: []
28
14
  description: A simple and lightweight gem to escalate rescued exceptions.
29
15
  email:
30
16
  - development@invoca.com