escalate 0.2.0 → 0.3.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
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