honeybadger 1.13.2 → 1.14.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 +7 -0
- data/Appraisals +60 -45
- data/CHANGELOG.md +30 -1
- data/Gemfile.lock +1 -1
- data/MIT-LICENSE +2 -1
- data/Rakefile +8 -4
- data/features/standalone.feature +73 -0
- data/features/step_definitions/rack_steps.rb +1 -2
- data/features/step_definitions/standalone_steps.rb +12 -0
- data/features/step_definitions/thor_steps.rb +4 -0
- data/features/support/env.rb +2 -0
- data/features/support/test.thor +22 -0
- data/features/thor.feature +5 -0
- data/gemfiles/binding_of_caller.gemfile +8 -0
- data/gemfiles/rails.gemfile +11 -0
- data/gemfiles/rake.gemfile +1 -1
- data/gemfiles/standalone.gemfile +7 -0
- data/gemfiles/thor.gemfile +8 -0
- data/honeybadger.gemspec +27 -11
- data/lib/honeybadger.rb +15 -10
- data/lib/honeybadger/configuration.rb +9 -4
- data/lib/honeybadger/dependency.rb +65 -0
- data/lib/honeybadger/exception_extensions.rb +35 -0
- data/lib/honeybadger/integrations.rb +5 -0
- data/lib/honeybadger/integrations/delayed_job.rb +20 -0
- data/lib/honeybadger/integrations/delayed_job/plugin.rb +31 -0
- data/lib/honeybadger/integrations/sidekiq.rb +17 -9
- data/lib/honeybadger/integrations/thor.rb +29 -0
- data/lib/honeybadger/notice.rb +47 -99
- data/lib/honeybadger/payload.rb +101 -0
- data/lib/honeybadger/rack.rb +8 -54
- data/lib/honeybadger/rack/error_notifier.rb +60 -0
- data/lib/honeybadger/rack/user_feedback.rb +74 -0
- data/lib/honeybadger/rack/user_informer.rb +28 -0
- data/lib/honeybadger/rails.rb +5 -4
- data/lib/honeybadger/railtie.rb +4 -3
- data/lib/honeybadger/user_feedback.rb +3 -67
- data/lib/honeybadger/user_informer.rb +3 -21
- data/spec/honeybadger/configuration_spec.rb +5 -1
- data/spec/honeybadger/dependency_spec.rb +134 -0
- data/spec/honeybadger/exception_extensions_spec.rb +40 -0
- data/spec/honeybadger/integrations/delayed_job_spec.rb +48 -0
- data/spec/honeybadger/integrations/sidekiq_spec.rb +60 -0
- data/spec/honeybadger/integrations/thor_spec.rb +29 -0
- data/spec/honeybadger/notice_spec.rb +137 -127
- data/spec/honeybadger/payload_spec.rb +162 -0
- data/spec/honeybadger/rack_spec.rb +6 -6
- data/spec/honeybadger/rails/action_controller_spec.rb +2 -0
- data/spec/honeybadger/rails_spec.rb +4 -2
- data/spec/honeybadger/user_feedback_spec.rb +2 -2
- data/spec/honeybadger/user_informer_spec.rb +3 -3
- metadata +49 -66
- data/gemfiles/rack.gemfile.lock +0 -125
- data/gemfiles/rails2.3.gemfile.lock +0 -141
- data/gemfiles/rails3.0.gemfile.lock +0 -193
- data/gemfiles/rails3.1.gemfile.lock +0 -203
- data/gemfiles/rails3.2.gemfile.lock +0 -201
- data/gemfiles/rails4.0.gemfile.lock +0 -197
- data/gemfiles/rails4.1.gemfile.lock +0 -202
- data/gemfiles/rake.gemfile.lock +0 -124
- data/gemfiles/sinatra.gemfile.lock +0 -124
data/lib/honeybadger.rb
CHANGED
@@ -4,6 +4,7 @@ require 'json'
|
|
4
4
|
require 'digest'
|
5
5
|
require 'logger'
|
6
6
|
|
7
|
+
require 'honeybadger/dependency'
|
7
8
|
require 'honeybadger/configuration'
|
8
9
|
require 'honeybadger/backtrace'
|
9
10
|
require 'honeybadger/notice'
|
@@ -12,12 +13,13 @@ require 'honeybadger/sender'
|
|
12
13
|
require 'honeybadger/stats'
|
13
14
|
require 'honeybadger/user_informer'
|
14
15
|
require 'honeybadger/user_feedback'
|
16
|
+
require 'honeybadger/integrations'
|
17
|
+
require 'honeybadger/exception_extensions'
|
15
18
|
|
16
19
|
require 'honeybadger/railtie' if defined?(Rails::Railtie)
|
17
|
-
require 'honeybadger/integrations/sidekiq'
|
18
20
|
|
19
21
|
module Honeybadger
|
20
|
-
VERSION = '1.
|
22
|
+
VERSION = '1.14.0'
|
21
23
|
LOG_PREFIX = "** [Honeybadger] "
|
22
24
|
|
23
25
|
HEADERS = {
|
@@ -171,11 +173,13 @@ module Honeybadger
|
|
171
173
|
private
|
172
174
|
|
173
175
|
def send_notice(notice)
|
176
|
+
return false unless sender
|
177
|
+
|
174
178
|
if configuration.public?
|
175
179
|
if configuration.async?
|
176
180
|
configuration.async.call(notice)
|
177
181
|
else
|
178
|
-
notice
|
182
|
+
Honeybadger.sender.send_to_honeybadger(notice)
|
179
183
|
end
|
180
184
|
end
|
181
185
|
end
|
@@ -188,13 +192,14 @@ module Honeybadger
|
|
188
192
|
end
|
189
193
|
|
190
194
|
def unwrap_exception(exception)
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
else
|
196
|
-
exception
|
197
|
-
end
|
195
|
+
exception.respond_to?(:original_exception) && exception.original_exception ||
|
196
|
+
exception.respond_to?(:continued_exception) && exception.continued_exception ||
|
197
|
+
exception.respond_to?(:cause) && exception.cause ||
|
198
|
+
exception
|
198
199
|
end
|
199
200
|
end
|
200
201
|
end
|
202
|
+
|
203
|
+
unless defined?(Rails)
|
204
|
+
Honeybadger::Dependency.inject!
|
205
|
+
end
|
@@ -8,7 +8,8 @@ module Honeybadger
|
|
8
8
|
:params_filters, :project_root, :port, :protocol, :proxy_host, :proxy_pass,
|
9
9
|
:proxy_port, :proxy_user, :secure, :use_system_ssl_cert_chain, :framework,
|
10
10
|
:user_information, :feedback, :rescue_rake_exceptions, :source_extract_radius,
|
11
|
-
:send_request_session, :debug, :fingerprint, :hostname, :
|
11
|
+
:send_request_session, :debug, :fingerprint, :hostname, :features, :metrics,
|
12
|
+
:log_exception_on_send_failure, :send_local_variables].freeze
|
12
13
|
|
13
14
|
# The API key for your project, found on the project edit form.
|
14
15
|
attr_accessor :api_key
|
@@ -100,6 +101,9 @@ module Honeybadger
|
|
100
101
|
# +true+ to send session data, +false+ to exclude
|
101
102
|
attr_accessor :send_request_session
|
102
103
|
|
104
|
+
# +true+ to send local variables, +false+ to exclude
|
105
|
+
attr_accessor :send_local_variables
|
106
|
+
|
103
107
|
# +true+ to log extra debug info, +false+ to suppress
|
104
108
|
attr_accessor :debug
|
105
109
|
|
@@ -175,11 +179,12 @@ module Honeybadger
|
|
175
179
|
@rescue_rake_exceptions = nil
|
176
180
|
@source_extract_radius = 2
|
177
181
|
@send_request_session = true
|
182
|
+
@send_local_variables = false
|
178
183
|
@debug = false
|
179
184
|
@log_exception_on_send_failure = false
|
180
185
|
@hostname = Socket.gethostname
|
181
186
|
@metrics = true
|
182
|
-
@features = {
|
187
|
+
@features = {'notices' => true, 'local_variables' => true}
|
183
188
|
@limit = nil
|
184
189
|
@feedback = true
|
185
190
|
end
|
@@ -283,10 +288,10 @@ module Honeybadger
|
|
283
288
|
#
|
284
289
|
# Examples
|
285
290
|
#
|
286
|
-
# config.async = Proc.new { |notice| Thread.new { notice
|
291
|
+
# config.async = Proc.new { |notice| Thread.new { Honeybadger.sender.send_to_honeybadger(notice) } }
|
287
292
|
#
|
288
293
|
# config.async do |notice|
|
289
|
-
# Thread.new { notice
|
294
|
+
# Thread.new { Honeybadger.sender.send_to_honeybadger(notice) }
|
290
295
|
# end
|
291
296
|
#
|
292
297
|
# Returns configured async handler (should respond to #call(notice))
|
@@ -0,0 +1,65 @@
|
|
1
|
+
module Honeybadger
|
2
|
+
class Dependency
|
3
|
+
class << self
|
4
|
+
@@instances = []
|
5
|
+
|
6
|
+
def instances
|
7
|
+
@@instances
|
8
|
+
end
|
9
|
+
|
10
|
+
def register
|
11
|
+
instances << new.tap { |d| d.instance_eval(&Proc.new) }
|
12
|
+
end
|
13
|
+
|
14
|
+
def inject!
|
15
|
+
instances.each do |dependency|
|
16
|
+
dependency.inject! if dependency.ok?
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def reset!
|
21
|
+
instances.each(&:reset!)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def initialize
|
26
|
+
@injected = false
|
27
|
+
@requirements = []
|
28
|
+
@injections = []
|
29
|
+
end
|
30
|
+
|
31
|
+
def requirement
|
32
|
+
@requirements << Proc.new
|
33
|
+
end
|
34
|
+
|
35
|
+
def injection
|
36
|
+
@injections << Proc.new
|
37
|
+
end
|
38
|
+
|
39
|
+
def ok?
|
40
|
+
!@injected && @requirements.all?(&:call)
|
41
|
+
rescue => e
|
42
|
+
Honeybadger.write_verbose_log("Exception caught while verifying dependency: #{e.class} -- #{e.message}", :error)
|
43
|
+
false
|
44
|
+
end
|
45
|
+
|
46
|
+
def inject!
|
47
|
+
@injections.each(&:call)
|
48
|
+
rescue => e
|
49
|
+
Honeybadger.write_verbose_log("Exception caught while injecting dependency: #{e.class} -- #{e.message}", :error)
|
50
|
+
false
|
51
|
+
ensure
|
52
|
+
@injected = true
|
53
|
+
end
|
54
|
+
|
55
|
+
def reset!
|
56
|
+
@injected = false
|
57
|
+
end
|
58
|
+
|
59
|
+
def injected?
|
60
|
+
@injected
|
61
|
+
end
|
62
|
+
|
63
|
+
attr_reader :requirements, :injections
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Honeybadger
|
2
|
+
module ExceptionExtensions
|
3
|
+
module Bindings
|
4
|
+
def self.included(base)
|
5
|
+
base.send(:alias_method, :set_backtrace_without_honeybadger, :set_backtrace)
|
6
|
+
base.send(:alias_method, :set_backtrace, :set_backtrace_with_honeybadger)
|
7
|
+
end
|
8
|
+
|
9
|
+
def set_backtrace_with_honeybadger(*args, &block)
|
10
|
+
if caller.none? { |loc| loc.match(Honeybadger::Backtrace::Line::INPUT_FORMAT) && Regexp.last_match(1) == __FILE__ }
|
11
|
+
@__honeybadger_bindings_stack = binding.callers.drop(1)
|
12
|
+
end
|
13
|
+
|
14
|
+
set_backtrace_without_honeybadger(*args, &block)
|
15
|
+
end
|
16
|
+
|
17
|
+
def __honeybadger_bindings_stack
|
18
|
+
@__honeybadger_bindings_stack || []
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
module NullBindings
|
23
|
+
def __honeybadger_bindings_stack
|
24
|
+
[]
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
begin
|
31
|
+
require 'binding_of_caller'
|
32
|
+
Exception.send(:include, Honeybadger::ExceptionExtensions::Bindings)
|
33
|
+
rescue LoadError
|
34
|
+
Exception.send(:include, Honeybadger::ExceptionExtensions::NullBindings)
|
35
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Honeybadger
|
2
|
+
Dependency.register do
|
3
|
+
requirement { defined?(::Delayed::Plugin) }
|
4
|
+
requirement { defined?(::Delayed::Worker.plugins) }
|
5
|
+
requirement do
|
6
|
+
if delayed_job_honeybadger = defined?(::Delayed::Plugins::Honeybadger)
|
7
|
+
Honeybadger.write_verbose_log("Support for Delayed Job has been moved " \
|
8
|
+
"to the honeybadger gem. Please remove " \
|
9
|
+
"delayed_job_honeybadger from your " \
|
10
|
+
"Gemfile.", :warn)
|
11
|
+
end
|
12
|
+
!delayed_job_honeybadger
|
13
|
+
end
|
14
|
+
|
15
|
+
injection do
|
16
|
+
require 'honeybadger/integrations/delayed_job/plugin'
|
17
|
+
::Delayed::Worker.plugins << Integrations::DelayedJob::Plugin
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Honeybadger
|
2
|
+
module Integrations
|
3
|
+
module DelayedJob
|
4
|
+
class Plugin < ::Delayed::Plugin
|
5
|
+
callbacks do |lifecycle|
|
6
|
+
lifecycle.around(:invoke_job) do |job, &block|
|
7
|
+
begin
|
8
|
+
block.call(job)
|
9
|
+
rescue Exception => error
|
10
|
+
::Honeybadger.notify_or_ignore(
|
11
|
+
:error_class => error.class.name,
|
12
|
+
:error_message => "#{ error.class.name }: #{ error.message }",
|
13
|
+
:backtrace => error.backtrace,
|
14
|
+
:context => {
|
15
|
+
:job_id => job.id,
|
16
|
+
:handler => job.handler,
|
17
|
+
:last_error => job.last_error,
|
18
|
+
:attempts => job.attempts,
|
19
|
+
:queue => job.queue
|
20
|
+
}
|
21
|
+
)
|
22
|
+
raise error
|
23
|
+
ensure
|
24
|
+
::Honeybadger.context.clear!
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -9,18 +9,26 @@ module Honeybadger
|
|
9
9
|
end
|
10
10
|
end
|
11
11
|
end
|
12
|
-
end
|
13
12
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
13
|
+
Dependency.register do
|
14
|
+
requirement { defined?(::Sidekiq) }
|
15
|
+
|
16
|
+
injection do
|
17
|
+
::Sidekiq.configure_server do |config|
|
18
|
+
config.server_middleware do |chain|
|
19
|
+
chain.add Integrations::Sidekiq::Middleware
|
20
|
+
end
|
21
|
+
end
|
18
22
|
end
|
19
23
|
end
|
20
|
-
end
|
21
24
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
+
Dependency.register do
|
26
|
+
requirement { defined?(::Sidekiq::VERSION) && ::Sidekiq::VERSION > '3' }
|
27
|
+
|
28
|
+
injection do
|
29
|
+
::Sidekiq.configure_server do |config|
|
30
|
+
config.error_handlers << Proc.new {|ex,context| Honeybadger.notify_or_ignore(ex, :parameters => context) }
|
31
|
+
end
|
32
|
+
end
|
25
33
|
end
|
26
34
|
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Honeybadger
|
2
|
+
module Integrations
|
3
|
+
module Thor
|
4
|
+
def self.included(base)
|
5
|
+
base.class_eval do
|
6
|
+
no_commands do
|
7
|
+
alias_method :invoke_command_without_honeybadger, :invoke_command
|
8
|
+
alias_method :invoke_command, :invoke_command_with_honeybadger
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def invoke_command_with_honeybadger(*args)
|
14
|
+
invoke_command_without_honeybadger(*args)
|
15
|
+
rescue Exception => e
|
16
|
+
Honeybadger.notify_or_ignore(e)
|
17
|
+
raise
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
Dependency.register do
|
23
|
+
requirement { defined?(::Thor) }
|
24
|
+
|
25
|
+
injection do
|
26
|
+
Thor.send(:include, Integrations::Thor)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
data/lib/honeybadger/notice.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'honeybadger/payload'
|
1
2
|
require 'socket'
|
2
3
|
|
3
4
|
module Honeybadger
|
@@ -85,8 +86,15 @@ module Honeybadger
|
|
85
86
|
# The api_key to use when sending notice (optional)
|
86
87
|
attr_reader :api_key
|
87
88
|
|
89
|
+
# Local variables are extracted from first frame of backtrace
|
90
|
+
attr_reader :local_variables
|
91
|
+
|
92
|
+
# Additional features to enable/disable
|
93
|
+
attr_reader :features
|
94
|
+
|
88
95
|
def initialize(args)
|
89
96
|
self.args = args
|
97
|
+
self.features = args[:features] || {}
|
90
98
|
self.exception = args[:exception]
|
91
99
|
self.project_root = args[:project_root]
|
92
100
|
|
@@ -116,7 +124,7 @@ module Honeybadger
|
|
116
124
|
end
|
117
125
|
end
|
118
126
|
|
119
|
-
self.url =
|
127
|
+
self.url = args[:url] || rack_env(:url)
|
120
128
|
self.hostname = local_hostname
|
121
129
|
self.stats = Stats.all
|
122
130
|
self.api_key = args[:api_key]
|
@@ -124,19 +132,17 @@ module Honeybadger
|
|
124
132
|
self.source_extract_radius = args[:source_extract_radius] || 2
|
125
133
|
self.source_extract = extract_source_from_backtrace
|
126
134
|
|
135
|
+
self.local_variables = send_local_variables? ? local_variables_from_exception(exception) : {}
|
136
|
+
|
127
137
|
self.send_request_session = args[:send_request_session].nil? ? true : args[:send_request_session]
|
128
138
|
|
129
139
|
find_session_data
|
130
140
|
clean_rack_request_data
|
131
141
|
also_use_rack_params_filters
|
132
|
-
clean_params
|
133
142
|
set_context
|
134
143
|
end
|
135
144
|
|
136
|
-
#
|
137
|
-
#
|
138
|
-
# Returns a reference to the error in Honeybadger, false if sender isn't
|
139
|
-
# configured
|
145
|
+
# Deprecated. Remove in 2.0.
|
140
146
|
def deliver
|
141
147
|
return false unless Honeybadger.sender
|
142
148
|
Honeybadger.sender.send_to_honeybadger(self)
|
@@ -146,7 +152,7 @@ module Honeybadger
|
|
146
152
|
#
|
147
153
|
# Returns JSON representation of notice
|
148
154
|
def as_json(options = {})
|
149
|
-
{
|
155
|
+
Payload.new({
|
150
156
|
:api_key => api_key,
|
151
157
|
:notifier => {
|
152
158
|
:name => notifier_name,
|
@@ -168,7 +174,8 @@ module Honeybadger
|
|
168
174
|
:params => parameters,
|
169
175
|
:session => session_data,
|
170
176
|
:cgi_data => cgi_data,
|
171
|
-
:context => context
|
177
|
+
:context => context,
|
178
|
+
:local_variables => local_variables
|
172
179
|
},
|
173
180
|
:server => {
|
174
181
|
:project_root => project_root,
|
@@ -176,7 +183,7 @@ module Honeybadger
|
|
176
183
|
:hostname => hostname,
|
177
184
|
:stats => stats
|
178
185
|
}
|
179
|
-
}
|
186
|
+
}, :filters => params_filters)
|
180
187
|
end
|
181
188
|
|
182
189
|
# Public: Creates JSON
|
@@ -235,8 +242,9 @@ module Honeybadger
|
|
235
242
|
:error_message, :backtrace_filters, :parameters, :params_filters,
|
236
243
|
:environment_filters, :session_data, :project_root, :url, :ignore,
|
237
244
|
:ignore_by_filters, :notifier_name, :notifier_url, :notifier_version,
|
238
|
-
:component, :action, :cgi_data, :environment_name, :hostname, :stats,
|
239
|
-
:source_extract, :source_extract_radius, :send_request_session,
|
245
|
+
:component, :action, :cgi_data, :environment_name, :hostname, :stats,
|
246
|
+
:context, :source_extract, :source_extract_radius, :send_request_session,
|
247
|
+
:api_key, :features, :local_variables
|
240
248
|
|
241
249
|
# Private: Arguments given in the initializer
|
242
250
|
attr_accessor :args
|
@@ -271,71 +279,6 @@ module Honeybadger
|
|
271
279
|
end
|
272
280
|
end
|
273
281
|
|
274
|
-
# Private: Removes non-serializable data from the given attribute.
|
275
|
-
# See #clean_unserializable_data
|
276
|
-
def clean_unserializable_data_from(attribute)
|
277
|
-
self.send(:"#{attribute}=", clean_unserializable_data(send(attribute)))
|
278
|
-
end
|
279
|
-
|
280
|
-
# Private: Removes non-serializable data. Allowed data types are strings, arrays,
|
281
|
-
# and hashes. All other types are converted to strings.
|
282
|
-
# TODO: move this onto Hash
|
283
|
-
def clean_unserializable_data(data, stack = [])
|
284
|
-
return "[possible infinite recursion halted]" if stack.any?{|item| item == data.object_id }
|
285
|
-
|
286
|
-
if data.respond_to?(:to_hash)
|
287
|
-
data.to_hash.inject({}) do |result, (key, value)|
|
288
|
-
result.merge(key => clean_unserializable_data(value, stack + [data.object_id]))
|
289
|
-
end
|
290
|
-
elsif data.respond_to?(:to_ary)
|
291
|
-
data.to_ary.collect do |value|
|
292
|
-
clean_unserializable_data(value, stack + [data.object_id])
|
293
|
-
end
|
294
|
-
else
|
295
|
-
data.to_s
|
296
|
-
end
|
297
|
-
end
|
298
|
-
|
299
|
-
# Internal: Filters query parameters from URL
|
300
|
-
#
|
301
|
-
# url - String URL to filter
|
302
|
-
#
|
303
|
-
# Returns filtered String URL
|
304
|
-
def filter_url(url)
|
305
|
-
return nil unless url =~ /\S/
|
306
|
-
|
307
|
-
url = url.dup
|
308
|
-
url.scan(/(?:^|&|\?)([^=?&]+)=([^&]+)/).each do |m|
|
309
|
-
next unless filter_key?(m[0])
|
310
|
-
url.gsub!(/#{m[1]}/, '[FILTERED]')
|
311
|
-
end
|
312
|
-
|
313
|
-
url
|
314
|
-
end
|
315
|
-
|
316
|
-
# Internal: Replaces the contents of params that match params_filters.
|
317
|
-
# TODO: extract this to a different class
|
318
|
-
def clean_params
|
319
|
-
clean_unserializable_data_from(:parameters)
|
320
|
-
filter(parameters)
|
321
|
-
if cgi_data
|
322
|
-
clean_unserializable_data_from(:cgi_data)
|
323
|
-
filter(cgi_data)
|
324
|
-
filter_cgi_data_params(cgi_data)
|
325
|
-
end
|
326
|
-
if session_data
|
327
|
-
clean_unserializable_data_from(:session_data)
|
328
|
-
filter(session_data)
|
329
|
-
end
|
330
|
-
end
|
331
|
-
|
332
|
-
def filter_cgi_data_params(cgi_data)
|
333
|
-
cgi_data.each_pair do |key, value|
|
334
|
-
next unless value.kind_of?(String) && key =~ /\A[A-Z_]+\Z/ && value =~ /\S/
|
335
|
-
cgi_data[key] = filter_url(value)
|
336
|
-
end
|
337
|
-
end
|
338
|
-
|
339
282
|
def clean_rack_request_data
|
340
283
|
if cgi_data
|
341
284
|
self.cgi_data = cgi_data.dup
|
@@ -381,28 +324,6 @@ module Honeybadger
|
|
381
324
|
end
|
382
325
|
end
|
383
326
|
|
384
|
-
def filter(hash)
|
385
|
-
if params_filters
|
386
|
-
hash.each do |key, value|
|
387
|
-
if filter_key?(key)
|
388
|
-
hash[key] = "[FILTERED]"
|
389
|
-
elsif value.respond_to?(:to_hash)
|
390
|
-
filter(hash[key])
|
391
|
-
end
|
392
|
-
end
|
393
|
-
end
|
394
|
-
end
|
395
|
-
|
396
|
-
def filter_key?(key)
|
397
|
-
params_filters.any? do |filter|
|
398
|
-
if filter.is_a?(Regexp)
|
399
|
-
key.to_s =~ filter
|
400
|
-
else
|
401
|
-
key.to_s.eql?(filter.to_s)
|
402
|
-
end
|
403
|
-
end
|
404
|
-
end
|
405
|
-
|
406
327
|
def find_session_data
|
407
328
|
if send_request_session
|
408
329
|
self.session_data = args[:session_data] || args[:session] || rack_session || {}
|
@@ -416,7 +337,8 @@ module Honeybadger
|
|
416
337
|
end
|
417
338
|
|
418
339
|
def set_context
|
419
|
-
self.context =
|
340
|
+
self.context = {}
|
341
|
+
self.context.merge!(Thread.current[:honeybadger_context]) if Thread.current[:honeybadger_context]
|
420
342
|
self.context.merge!(args[:context]) if args[:context]
|
421
343
|
self.context = nil if context.empty?
|
422
344
|
end
|
@@ -477,5 +399,31 @@ module Honeybadger
|
|
477
399
|
input = input[0...bytes] if input.respond_to?(:size) && input.size > bytes
|
478
400
|
input
|
479
401
|
end
|
402
|
+
|
403
|
+
# Internal: Fetch local variables from first frame of backtrace.
|
404
|
+
#
|
405
|
+
# exception - The Exception containing the bindings stack.
|
406
|
+
#
|
407
|
+
# Returns a Hash of local variables
|
408
|
+
def local_variables_from_exception(exception)
|
409
|
+
return {} unless Exception === exception
|
410
|
+
return {} if exception.__honeybadger_bindings_stack.empty?
|
411
|
+
|
412
|
+
if project_root
|
413
|
+
binding = exception.__honeybadger_bindings_stack.find { |b| b.eval('__FILE__') =~ /^#{Regexp.escape(project_root.to_s)}/ }
|
414
|
+
end
|
415
|
+
|
416
|
+
binding ||= exception.__honeybadger_bindings_stack[0]
|
417
|
+
|
418
|
+
vars = binding.eval('local_variables')
|
419
|
+
Hash[vars.map {|arg| [arg, binding.eval(arg.to_s)]}]
|
420
|
+
end
|
421
|
+
|
422
|
+
# Internal: Should local variables be sent?
|
423
|
+
#
|
424
|
+
# Returns true to send local_variables
|
425
|
+
def send_local_variables?
|
426
|
+
args[:send_local_variables] && features['local_variables']
|
427
|
+
end
|
480
428
|
end
|
481
429
|
end
|