honeybadger 4.1.0 → 4.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
2
  SHA256:
3
- metadata.gz: 0d010f2e523efe0185206367bd3d32bfd8984ea0b6e995432772eee392676a5a
4
- data.tar.gz: bdef4e603e16d0b256f2288bd2b37ebe52affa9b7803c37ef0ebfbb7bd931f14
3
+ metadata.gz: 4a6d163c5a87db64d1c5e591757d69dfd7be38854e01150c3ec4a86f041ea020
4
+ data.tar.gz: b3b56e28bd3f5885d5db6adf4d23d7f7ce7bdce8497ce62f68b3b267921a0eee
5
5
  SHA512:
6
- metadata.gz: 8c0b7043750663369c7521b5987942b50dc472cd84bc90c5c773ec870b7e37676091bff5ad51a6c3725a608abd012063ccf510a83936ceb3a8b540e00c864739
7
- data.tar.gz: 8653f1dd66da018309fd5dbb9f77f851a07be313822b79c830cd41b9f9222f602153dbb4314d174dac133521124ad27f5b44d984a3cf0f4e80b3c05baa78e5a8
6
+ metadata.gz: f4eeb6527e4de32f97020b8b19af675e17500138aafde1ee1a9541ebf9b6b09fa7f62987f63d3908c03646ff4dd2303d10460d930c2b3075a4df2054e7003371
7
+ data.tar.gz: 0ad30ae7ddf8a44d592cac241e5faa8b4c55589b2cba15d414e3c6d06df59f745fd2034d0cfa45334f0a81466d2b2904c65df368751af2ee87d6217ac2a5e60d
@@ -5,6 +5,15 @@ adheres to [Semantic Versioning](http://semver.org/).
5
5
 
6
6
  ## [Unreleased]
7
7
 
8
+ ## [4.2.0] - 2019-01-31
9
+ ### Changed
10
+ - Issue a Notification from a Sidekiq job when either the `sidekiq.attempt_threshold` is reached OR if the job defined retry threshold is reached, whichever comes first.
11
+ - Updated supported Ruby/Rails versions (MRI >= 2.3.0, JRuby >= 9.2, Rails >= 4.2)
12
+ https://docs.honeybadger.io/ruby/gem-reference/supported-versions.html
13
+
14
+ ### Added
15
+ - Get the right controller / action name in Rails, when using an exception app for custom error pages.
16
+
8
17
  ## [4.1.0] - 2018-10-16
9
18
  ### Added
10
19
  - Added flag `--skip-rails-load` to cli commands for optionally skipping Rails initialization when running from a Rails root.
@@ -1,17 +1,71 @@
1
1
  require 'forwardable'
2
2
 
3
3
  module Honeybadger
4
- # @api private
4
+ # +Honeybadger::Plugin+ defines the API for registering plugins with
5
+ # Honeybadger. Each plugin has requirements which must be satisified before
6
+ # executing the plugin's execution block(s). This allows us to detect
7
+ # optional dependencies and load the plugin for each dependency only if it's
8
+ # present in the application.
9
+ #
10
+ # See the plugins/ directory for examples of official plugins. If you're
11
+ # interested in developing a plugin for Honeybadger, see the Integration
12
+ # Guide: https://docs.honeybadger.io/ruby/gem-reference/integration.html
13
+ #
14
+ # @example
15
+ #
16
+ # require 'honeybadger/plugin'
17
+ # require 'honeybadger/ruby'
18
+ #
19
+ # module Honeybadger
20
+ # module Plugins
21
+ # # Register your plugin with an optional name. If the name (such as
22
+ # # "my_framework") is not provided, Honeybadger will try to infer the name
23
+ # # from the current file.
24
+ # Plugin.register 'my_framework' do
25
+ # requirement do
26
+ # # Check to see if the thing you're integrating with is loaded. Return true
27
+ # # if it is, or false if it isn't. An exception in this block is equivalent
28
+ # # to returning false. Multiple requirement blocks are supported.
29
+ # defined?(MyFramework)
30
+ # end
31
+ #
32
+ # execution do
33
+ # # Write your integration. This code will be executed only if all requirement
34
+ # # blocks return true. An exception in this block will disable the plugin.
35
+ # # Multiple execution blocks are supported.
36
+ # MyFramework.on_exception do |exception|
37
+ # Honeybadger.notify(exception)
38
+ # end
39
+ # end
40
+ # end
41
+ # end
42
+ # end
5
43
  class Plugin
44
+ # @api private
6
45
  CALLER_FILE = Regexp.new('\A(?:\w:)?([^:]+)(?=(:\d+))').freeze
7
46
 
8
47
  class << self
48
+ # @api private
9
49
  @@instances = {}
10
50
 
51
+ # @api private
11
52
  def instances
12
53
  @@instances
13
54
  end
14
55
 
56
+ # Register a new plugin with Honeybadger. See {#requirement} and {#execution}.
57
+ #
58
+ # @example
59
+ #
60
+ # Honeybadger::Plugin.register 'my_framework' do
61
+ # requirement { }
62
+ # execution { }
63
+ # end
64
+ #
65
+ # @param [String] name The optional name of the plugin. Should use
66
+ # +snake_case+. The name is inferred from the current file name if omitted.
67
+ #
68
+ # @return nil
15
69
  def register(name = nil)
16
70
  name ||= name_from_caller(caller) or
17
71
  raise(ArgumentError, 'Plugin name is required, but was nil.')
@@ -19,6 +73,7 @@ module Honeybadger
19
73
  instances[key] = new(name).tap { |d| d.instance_eval(&Proc.new) }
20
74
  end
21
75
 
76
+ # @api private
22
77
  def load!(config)
23
78
  instances.each_pair do |name, plugin|
24
79
  if config.load_plugin?(name)
@@ -29,6 +84,7 @@ module Honeybadger
29
84
  end
30
85
  end
31
86
 
87
+ # @api private
32
88
  def name_from_caller(caller)
33
89
  caller && caller[0].match(CALLER_FILE) or
34
90
  fail("Unable to determine name from caller: #{caller.inspect}")
@@ -36,6 +92,7 @@ module Honeybadger
36
92
  end
37
93
  end
38
94
 
95
+ # @api private
39
96
  class Execution
40
97
  extend Forwardable
41
98
 
@@ -54,6 +111,7 @@ module Honeybadger
54
111
  def_delegator :@config, :logger
55
112
  end
56
113
 
114
+ # @api private
57
115
  def initialize(name)
58
116
  @name = name
59
117
  @loaded = false
@@ -61,14 +119,53 @@ module Honeybadger
61
119
  @executions = []
62
120
  end
63
121
 
122
+ # Define a requirement. All requirement blocks must return +true+ for the
123
+ # plugin to be executed.
124
+ #
125
+ # @example
126
+ #
127
+ # Honeybadger::Plugin.register 'my_framework' do
128
+ # requirement { defined?(MyFramework) }
129
+ #
130
+ # # Honeybadger's configuration object is available inside
131
+ # # requirement blocks. It should generally not be used outside of
132
+ # # internal plugins. See +Config+.
133
+ # requirement { config[:'my_framework.enabled'] }
134
+ #
135
+ # execution { }
136
+ # end
137
+ #
138
+ # @return nil
64
139
  def requirement
65
140
  @requirements << Proc.new
66
141
  end
67
142
 
143
+ # Define an execution block. Execution blocks will be executed if all
144
+ # requirement blocks return +true+.
145
+ #
146
+ # @example
147
+ #
148
+ # Honeybadger::Plugin.register 'my_framework' do
149
+ # requirement { defined?(MyFramework) }
150
+ #
151
+ # execution do
152
+ # MyFramework.on_exception {|err| Honeybadger.notify(err) }
153
+ # end
154
+ #
155
+ # execution do
156
+ # # Honeybadger's configuration object is available inside
157
+ # # execution blocks. It should generally not be used outside of
158
+ # # internal plugins. See +Config+.
159
+ # MyFramework.use_middleware(MyMiddleware) if config[:'my_framework.use_middleware']
160
+ # end
161
+ # end
162
+ #
163
+ # @return nil
68
164
  def execution
69
165
  @executions << Proc.new
70
166
  end
71
167
 
168
+ # @api private
72
169
  def ok?(config)
73
170
  @requirements.all? {|r| Execution.new(config, &r).call }
74
171
  rescue => e
@@ -76,6 +173,7 @@ module Honeybadger
76
173
  false
77
174
  end
78
175
 
176
+ # @api private
79
177
  def load!(config)
80
178
  if @loaded
81
179
  config.logger.debug(sprintf('skip plugin name=%s reason=loaded', name))
@@ -95,16 +193,18 @@ module Honeybadger
95
193
  false
96
194
  end
97
195
 
196
+ # @api private
197
+ def loaded?
198
+ @loaded
199
+ end
200
+
98
201
  # @private
99
202
  # Used for testing only; don't normally call this. :)
100
203
  def reset!
101
204
  @loaded = false
102
205
  end
103
206
 
104
- def loaded?
105
- @loaded
106
- end
107
-
207
+ # @api private
108
208
  attr_reader :name, :requirements, :executions
109
209
  end
110
210
  end
@@ -33,6 +33,21 @@ module Honeybadger
33
33
  requirement { defined?(::Rails.application) && ::Rails.application }
34
34
 
35
35
  execution do
36
+ if ::Rails.application.config.exceptions_app.is_a?(::ActionDispatch::Routing::RouteSet)
37
+ Honeybadger.configure do |config|
38
+ config.before_notify do |notice|
39
+ begin
40
+ route_resolver = ::Rails.application.routes.recognize_path(notice.url)
41
+ notice.component = route_resolver[:controller]
42
+ notice.action = route_resolver[:action]
43
+ rescue ::ActionController::RoutingError
44
+ # if rails can't find the route (like assets)
45
+ # we just ignore and keep the old component / action
46
+ end
47
+ end
48
+ end
49
+ end
50
+
36
51
  require 'rack/request'
37
52
  if defined?(::ActionDispatch::DebugExceptions)
38
53
  # Rails 3.2.x+
@@ -25,7 +25,15 @@ module Honeybadger
25
25
  ::Sidekiq.configure_server do |sidekiq|
26
26
  sidekiq.error_handlers << lambda {|ex, params|
27
27
  job = params[:job] || params
28
- return if job['retry'.freeze] && job['retry_count'.freeze].to_i < config[:'sidekiq.attempt_threshold'].to_i
28
+ retry_count = job['retry_count'.freeze].to_i
29
+ retry_opt = job['retry'.freeze]
30
+ max_retries = if retry_opt.is_a?(Integer)
31
+ [retry_opt - 1, config[:'sidekiq.attempt_threshold'].to_i].min
32
+ else
33
+ config[:'sidekiq.attempt_threshold'].to_i
34
+ end
35
+
36
+ return if retry_opt && retry_count < max_retries
29
37
  opts = {parameters: params}
30
38
  opts[:component] = job['wrapped'.freeze] || job['class'.freeze] if config[:'sidekiq.use_component']
31
39
  Honeybadger.notify(ex, opts)
@@ -1,4 +1,4 @@
1
1
  module Honeybadger
2
2
  # The current String Honeybadger version.
3
- VERSION = '4.1.0'.freeze
3
+ VERSION = '4.2.0'.freeze
4
4
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: honeybadger
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.1.0
4
+ version: 4.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Honeybadger Industries LLC
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-10-16 00:00:00.000000000 Z
11
+ date: 2019-01-31 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Make managing application errors a more pleasant experience.
14
14
  email: