honeybadger 6.6.2 → 6.7.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: 03a414b7ec784574a3164541f03d9e2b60d3a4af1d09b754d5c630282b3f0c12
4
- data.tar.gz: 26afeb772bb5e998ed9a15a213697b72d3415ffadfc858fc1419913daa5ca500
3
+ metadata.gz: afa4582b4bb18d1f9afc94a2c551ceb45643ef57be27e071f4878970bde4dfdb
4
+ data.tar.gz: e80f53bbd49fd9db0d0334b5fceb9d0153a4e78272fb460209e6741300299e0d
5
5
  SHA512:
6
- metadata.gz: 7ac887b4d796a351c0578cd52b492ca5e75a0232ff9f8fb1ab5f323608bfae9224d1e46a6ae8bd928b88cc5e424f65e5683e204c8c14ab9c7c639d76de651522
7
- data.tar.gz: 0ba659e647134528493c16665e40efa33d7ef4ad13af4472005119d807941d4e3c6be047671d8a0588b3b064b71a8cf6d12d3a7402287e029cf4f66dd5173575
6
+ metadata.gz: d4086244d6d9857f5a49be22a889ca5b3b9bb789bc9015ff08732810428930e03d9b0e4b56149f670c3b1e5321497d795c5af9f21290630b80ed83c117aaa71d
7
+ data.tar.gz: f81135eefd9c61f33f27666e3e7ea7c94537dddaa19cc5e770765505f322ad62bf2096469a7abc2395bb1f0e78a9ea43309592c3580aae47e158299178cf6dd1
data/CHANGELOG.md CHANGED
@@ -1,6 +1,14 @@
1
1
  # Change Log
2
2
 
3
3
 
4
+ ## [6.7.0](https://github.com/honeybadger-io/honeybadger-ruby/compare/v6.6.2...v6.7.0) (2026-06-05)
5
+
6
+
7
+ ### Features
8
+
9
+ * add after_notify hooks ([#825](https://github.com/honeybadger-io/honeybadger-ruby/issues/825)) ([950fee2](https://github.com/honeybadger-io/honeybadger-ruby/commit/950fee2bb2ab81ebbfa20ea34b36045bd6b57034))
10
+ * make backtrace limit configurable ([#824](https://github.com/honeybadger-io/honeybadger-ruby/issues/824)) ([f62ce3a](https://github.com/honeybadger-io/honeybadger-ruby/commit/f62ce3ab09ffa497fbfb2ec1fa193359b66b1a23))
11
+
4
12
  ## [6.6.2](https://github.com/honeybadger-io/honeybadger-ruby/compare/v6.6.0...v6.6.1) (2026-05-29)
5
13
 
6
14
 
@@ -4,6 +4,8 @@ module Honeybadger
4
4
  # @api private
5
5
  # Front end to parsing the backtrace for each notice.
6
6
  class Backtrace
7
+ DEFAULT_LIMIT = 1000
8
+
7
9
  # Handles backtrace parsing line by line.
8
10
  class Line
9
11
  # Backtrace line regexp (optionally allowing leading X: for windows support).
@@ -122,19 +124,20 @@ module Honeybadger
122
124
  Line.parse(unparsed_line.to_s, opts)
123
125
  end.compact
124
126
 
125
- new(lines)
127
+ new(lines, opts.fetch(:limit, DEFAULT_LIMIT))
126
128
  end
127
129
 
128
- def initialize(lines)
130
+ def initialize(lines, limit = DEFAULT_LIMIT)
129
131
  self.lines = lines
130
132
  self.application_lines = lines.select(&:application?)
133
+ self.limit = limit || DEFAULT_LIMIT
131
134
  end
132
135
 
133
136
  # Convert Backtrace to arry.
134
137
  #
135
138
  # Returns array containing backtrace lines.
136
139
  def to_ary
137
- lines.take(1000).map { |l| {number: l.filtered_number, file: l.filtered_file, method: l.filtered_method, source: l.source} }
140
+ lines.take(limit.clamp(0..)).map { |l| {number: l.filtered_number, file: l.filtered_file, method: l.filtered_method, source: l.source} }
138
141
  end
139
142
  alias_method :to_a, :to_ary
140
143
 
@@ -172,6 +175,8 @@ module Honeybadger
172
175
 
173
176
  attr_writer :lines, :application_lines
174
177
 
178
+ attr_accessor :limit
179
+
175
180
  class << self
176
181
  private
177
182
 
@@ -1,5 +1,6 @@
1
1
  require "socket"
2
2
  require "honeybadger/breadcrumbs/active_support"
3
+ require "honeybadger/backtrace"
3
4
 
4
5
  module Honeybadger
5
6
  class Config
@@ -321,6 +322,11 @@ module Honeybadger
321
322
  default: 2,
322
323
  type: Integer
323
324
  },
325
+ "exceptions.backtrace_limit": {
326
+ description: "The maximum number of backtrace lines to include in error reports.",
327
+ default: Backtrace::DEFAULT_LIMIT,
328
+ type: Integer
329
+ },
324
330
  "exceptions.local_variables": {
325
331
  description: "Enable sending local variables. Requires binding_of_caller to be loaded.",
326
332
  default: false,
@@ -89,21 +89,61 @@ module Honeybadger
89
89
  def before_notify(action = nil, &block)
90
90
  hooks = Array(get(:before_notify)).dup
91
91
 
92
- if action && validate_before_action(action, "notify")
92
+ if action && validate_hook_action(action, "before notify", 1)
93
93
  hooks << action
94
- elsif block_given? && validate_before_action(block, "notify")
94
+ elsif block_given? && validate_hook_action(block, "before notify", 1)
95
95
  hooks << block
96
96
  end
97
97
 
98
98
  hash[:before_notify] = hooks
99
99
  end
100
100
 
101
+ # Run a hook after each error notice delivery attempt.
102
+ #
103
+ # The hook is called for every backend response, including successful
104
+ # deliveries. Response codes are usually HTTP status integers, but may be
105
+ # symbols such as :stubbed or :error for non-server backends or connection
106
+ # failures. Filter with exact response codes (e.g. `response.code == 413`)
107
+ # rather than broad integer comparisons, or use `response.success?`.
108
+ # (Note: `response.error_message` may raise for non-HTTP responses like `:stubbed`.)
109
+ #
110
+ # Prefer `Honeybadger.event` for reporting failed notice deliveries. Calling
111
+ # `Honeybadger.notify` from this hook can trigger another after_notify call;
112
+ # guard against self-reporting loops if a notice must be sent.
113
+ #
114
+ # @example Report oversized notice payloads
115
+ # config.after_notify do |notice, response|
116
+ # next unless response.code == 413
117
+ #
118
+ # Honeybadger.event("honeybadger.notice_rejected", {
119
+ # reason: "payload_too_large",
120
+ # notice_id: notice.id,
121
+ # payload_bytes: notice.to_json.bytesize
122
+ # })
123
+ # end
124
+ #
125
+ # @yieldparam notice [Honeybadger::Notice] The notice that was sent.
126
+ # @yieldparam response [Honeybadger::Backend::Response] The backend response.
127
+ # @return [Array<Proc>] configured hooks
128
+ # @api public
129
+ def after_notify(action = nil, &block)
130
+ hooks = Array(get(:after_notify)).dup
131
+
132
+ if action && validate_hook_action(action, "after notify", 2)
133
+ hooks << action
134
+ elsif block_given? && validate_hook_action(block, "after notify", 2)
135
+ hooks << block
136
+ end
137
+
138
+ hash[:after_notify] = hooks
139
+ end
140
+
101
141
  def before_event(action = nil, &block)
102
142
  hooks = Array(get(:before_event)).dup
103
143
 
104
- if action && validate_before_action(action, "event")
144
+ if action && validate_hook_action(action, "before event", 1)
105
145
  hooks << action
106
- elsif block_given? && validate_before_action(block, "event")
146
+ elsif block_given? && validate_hook_action(block, "before event", 1)
107
147
  hooks << block
108
148
  end
109
149
 
@@ -139,18 +179,18 @@ module Honeybadger
139
179
 
140
180
  private
141
181
 
142
- def validate_before_action(action, type)
182
+ def validate_hook_action(action, name, arity)
143
183
  if !action.respond_to?(:call)
144
184
  logger.warn(
145
- "You attempted to add a before #{type} hook that does not respond " \
185
+ "You attempted to add a #{name} hook that does not respond " \
146
186
  "to #call. We are discarding this hook so your intended behavior " \
147
187
  "will not occur."
148
188
  )
149
189
  false
150
- elsif action.arity != 1
190
+ elsif action.arity != arity
151
191
  logger.warn(
152
- "You attempted to add a before #{type} hook that has an arity " \
153
- "other than one. We are discarding this hook so your intended " \
192
+ "You attempted to add a #{name} hook that has an arity " \
193
+ "other than #{arity}. We are discarding this hook so your intended " \
154
194
  "behavior will not occur."
155
195
  )
156
196
  false
@@ -92,6 +92,10 @@ module Honeybadger
92
92
  (ruby[:before_notify] || []).clone
93
93
  end
94
94
 
95
+ def after_notify_hooks
96
+ (ruby[:after_notify] || []).clone
97
+ end
98
+
95
99
  def before_event_hooks
96
100
  (ruby[:before_event] || []).clone
97
101
  end
@@ -509,7 +509,8 @@ module Honeybadger
509
509
  backtrace,
510
510
  filters: construct_backtrace_filters(opts),
511
511
  config: config,
512
- source_radius: config[:"exceptions.source_radius"]
512
+ source_radius: config[:"exceptions.source_radius"],
513
+ limit: config[:"exceptions.backtrace_limit"]
513
514
  ).to_a
514
515
  end
515
516
 
@@ -1,4 +1,4 @@
1
1
  module Honeybadger
2
2
  # The current String Honeybadger version.
3
- VERSION = "6.6.2".freeze
3
+ VERSION = "6.7.0".freeze
4
4
  end
@@ -46,7 +46,9 @@ module Honeybadger
46
46
  end
47
47
 
48
48
  def send_now(msg)
49
- handle_response(msg, notify_backend(msg))
49
+ response = notify_backend(msg)
50
+ run_after_notify_hooks(msg, response)
51
+ handle_response(msg, response)
50
52
  end
51
53
 
52
54
  def shutdown(force = false)
@@ -189,6 +191,21 @@ module Honeybadger
189
191
  backend.notify(:notices, payload)
190
192
  end
191
193
 
194
+ def run_after_notify_hooks(msg, response)
195
+ config.after_notify_hooks.each do |hook|
196
+ with_error_handling { hook.call(msg, response) }
197
+ end
198
+ end
199
+
200
+ def with_error_handling
201
+ yield
202
+ rescue => ex
203
+ error {
204
+ msg = "Rescued an error in an after notify hook class=%s message=%s\n\t%s"
205
+ sprintf(msg, ex.class, ex.message.dump, Array(ex.backtrace).join("\n\t"))
206
+ }
207
+ end
208
+
192
209
  def calc_throttle_interval
193
210
  ((BASE_THROTTLE**throttle) - 1).round(3)
194
211
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: honeybadger
3
3
  version: !ruby/object:Gem::Version
4
- version: 6.6.2
4
+ version: 6.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Honeybadger Industries LLC