honeybadger 3.2.0 → 3.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 +5 -5
- data/CHANGELOG.md +10 -0
- data/README.md +1 -1
- data/lib/honeybadger.rb +0 -7
- data/lib/honeybadger/agent.rb +112 -135
- data/lib/honeybadger/backend.rb +1 -0
- data/lib/honeybadger/backend/base.rb +22 -20
- data/lib/honeybadger/backend/debug.rb +3 -3
- data/lib/honeybadger/backend/server.rb +7 -12
- data/lib/honeybadger/backend/test.rb +7 -10
- data/lib/honeybadger/backtrace.rb +9 -8
- data/lib/honeybadger/cli.rb +1 -0
- data/lib/honeybadger/cli/heroku.rb +3 -3
- data/lib/honeybadger/cli/test.rb +1 -1
- data/lib/honeybadger/config.rb +6 -19
- data/lib/honeybadger/config/defaults.rb +2 -0
- data/lib/honeybadger/const.rb +11 -3
- data/lib/honeybadger/context_manager.rb +3 -1
- data/lib/honeybadger/conversions.rb +4 -3
- data/lib/honeybadger/init/rails.rb +2 -0
- data/lib/honeybadger/init/rake.rb +2 -1
- data/lib/honeybadger/init/ruby.rb +2 -0
- data/lib/honeybadger/init/sinatra.rb +3 -0
- data/lib/honeybadger/logging.rb +5 -4
- data/lib/honeybadger/notice.rb +63 -49
- data/lib/honeybadger/plugin.rb +3 -3
- data/lib/honeybadger/plugins/rails.rb +6 -6
- data/lib/honeybadger/plugins/resque.rb +3 -3
- data/lib/honeybadger/plugins/sidekiq.rb +1 -1
- data/lib/honeybadger/rack/error_notifier.rb +2 -3
- data/lib/honeybadger/rack/user_feedback.rb +8 -2
- data/lib/honeybadger/rack/user_informer.rb +2 -2
- data/lib/honeybadger/singleton.rb +46 -11
- data/lib/honeybadger/util/request_hash.rb +2 -2
- data/lib/honeybadger/util/request_payload.rb +4 -4
- data/lib/honeybadger/util/revision.rb +2 -2
- data/lib/honeybadger/util/sanitizer.rb +2 -2
- data/lib/honeybadger/version.rb +2 -2
- data/lib/honeybadger/worker.rb +7 -18
- metadata +3 -3
@@ -18,17 +18,20 @@ module Honeybadger
|
|
18
18
|
403 => "The API key is invalid. Please check your API key and try again.".freeze
|
19
19
|
}.freeze
|
20
20
|
|
21
|
-
#
|
21
|
+
# Initializes the Response instance.
|
22
22
|
#
|
23
|
-
# response
|
24
|
-
#
|
25
|
-
#
|
26
|
-
#
|
27
|
-
# body - The String body of the response.
|
28
|
-
# message - The String message returned by the server (or set by the
|
29
|
-
# backend in the case of an :error code).
|
23
|
+
# @overload initialize(response)
|
24
|
+
# Creates an instance from a +Net::HTTPResponse+.
|
25
|
+
# @param [Net::HTTPResponse] response With 1 argument, the code, body,
|
26
|
+
# and message will be determined automatically.
|
30
27
|
#
|
31
|
-
#
|
28
|
+
# @overload initialize(code, body, message)
|
29
|
+
# Creates an instance from parameters.
|
30
|
+
# @param [Integer] code The status code. May also be :error for requests
|
31
|
+
# which failed to reach the server.
|
32
|
+
# @param [String] body The String body of the response.
|
33
|
+
# @param [String] message The String message returned by the server (or
|
34
|
+
# set by the backend in the case of an :error code).
|
32
35
|
def initialize(*args)
|
33
36
|
if (response = args.first).kind_of?(Net::HTTPResponse)
|
34
37
|
@code, @body, @message = response.code.to_i, response.body.to_s, response.message
|
@@ -73,26 +76,25 @@ module Honeybadger
|
|
73
76
|
@config = config
|
74
77
|
end
|
75
78
|
|
76
|
-
#
|
77
|
-
#
|
78
|
-
# feature - A Symbol feature name (corresponds to HTTP endpoint). Current
|
79
|
-
# options are: `:notices`, `:deploys`, `:ping`.
|
80
|
-
# payload - Any Object responding to `#to_json`.
|
81
|
-
#
|
82
|
-
# Examples
|
79
|
+
# Process payload for feature.
|
83
80
|
#
|
81
|
+
# @example
|
84
82
|
# backend.notify(:notices, Notice.new(...))
|
85
83
|
#
|
86
|
-
#
|
84
|
+
# @param [Symbol] feature The feature name (corresponds to HTTP
|
85
|
+
# endpoint). Current options are: `:notices`, `:deploys`, `:ping`.
|
86
|
+
# @param [#to_json] payload The JSON payload to send.
|
87
|
+
#
|
88
|
+
# @raise NotImplementedError
|
87
89
|
def notify(feature, payload)
|
88
90
|
raise NotImplementedError, 'must define #notify on subclass.'
|
89
91
|
end
|
90
92
|
|
91
|
-
#
|
93
|
+
# Does a check in using the input id.
|
92
94
|
#
|
93
|
-
# id
|
95
|
+
# @param [String] id The unique check_in id.
|
94
96
|
#
|
95
|
-
#
|
97
|
+
# @raise NotImplementedError
|
96
98
|
def check_in(id)
|
97
99
|
raise NotImplementedError, 'must define #check_in on subclass.'
|
98
100
|
end
|
@@ -2,9 +2,9 @@ require 'honeybadger/backend/null'
|
|
2
2
|
|
3
3
|
module Honeybadger
|
4
4
|
module Backend
|
5
|
-
#
|
6
|
-
#
|
7
|
-
#
|
5
|
+
# Logs the notice payload rather than sending it. The purpose of this
|
6
|
+
# backend is primarily for programmatically inspecting JSON payloads in
|
7
|
+
# integration tests.
|
8
8
|
class Debug < Null
|
9
9
|
def notify(feature, payload)
|
10
10
|
logger.unknown("notifying debug backend of feature=#{feature}\n\t#{payload.to_json}")
|
@@ -24,12 +24,12 @@ module Honeybadger
|
|
24
24
|
super
|
25
25
|
end
|
26
26
|
|
27
|
-
#
|
27
|
+
# Post payload to endpoint for feature.
|
28
28
|
#
|
29
|
-
# feature
|
30
|
-
# payload
|
29
|
+
# @param [Symbol] feature The feature which is being notified.
|
30
|
+
# @param [#to_json] payload The JSON payload to send.
|
31
31
|
#
|
32
|
-
#
|
32
|
+
# @return [Response]
|
33
33
|
def notify(feature, payload)
|
34
34
|
ENDPOINTS[feature] or raise(BackendError, "Unknown feature: #{feature}")
|
35
35
|
Response.new(@http.post(ENDPOINTS[feature], payload, payload_headers(payload)))
|
@@ -37,11 +37,11 @@ module Honeybadger
|
|
37
37
|
Response.new(:error, nil, "HTTP Error: #{e.class}")
|
38
38
|
end
|
39
39
|
|
40
|
-
#
|
40
|
+
# Does a check in using the input id.
|
41
41
|
#
|
42
|
-
# id
|
42
|
+
# @param [String] id The unique check_in id.
|
43
43
|
#
|
44
|
-
#
|
44
|
+
# @return [Response]
|
45
45
|
def check_in(id)
|
46
46
|
Response.new(@http.get("#{CHECK_IN_ENDPOINT}/#{id}"))
|
47
47
|
rescue *HTTP_ERRORS => e
|
@@ -50,11 +50,6 @@ module Honeybadger
|
|
50
50
|
|
51
51
|
private
|
52
52
|
|
53
|
-
# Internal: Construct headers for supported payloads.
|
54
|
-
#
|
55
|
-
# payload - The payload object.
|
56
|
-
#
|
57
|
-
# Returns Hash headers if supported, otherwise nil.
|
58
53
|
def payload_headers(payload)
|
59
54
|
if payload.respond_to?(:api_key) && payload.api_key
|
60
55
|
{
|
@@ -3,34 +3,31 @@ require 'honeybadger/backend/null'
|
|
3
3
|
module Honeybadger
|
4
4
|
module Backend
|
5
5
|
class Test < Null
|
6
|
-
#
|
7
|
-
#
|
8
|
-
# Examples
|
6
|
+
# The notification list.
|
9
7
|
#
|
8
|
+
# @example
|
10
9
|
# Test.notifications[:notices] # => [Notice, Notice, ...]
|
11
10
|
#
|
12
|
-
#
|
11
|
+
# @return [Hash] Notifications hash.
|
13
12
|
def self.notifications
|
14
13
|
@notifications ||= Hash.new {|h,k| h[k] = [] }
|
15
14
|
end
|
16
15
|
|
17
|
-
#
|
18
|
-
#
|
19
|
-
# Examples
|
16
|
+
# @api public
|
17
|
+
# The check in list.
|
20
18
|
#
|
19
|
+
# @example
|
21
20
|
# Test.check_ins # => ["foobar", "danny", ...]
|
22
21
|
#
|
23
|
-
#
|
22
|
+
# @return [Array<Object>] List of check ins.
|
24
23
|
def self.check_ins
|
25
24
|
@check_ins ||= []
|
26
25
|
end
|
27
26
|
|
28
|
-
# Internal: Local helper.
|
29
27
|
def notifications
|
30
28
|
self.class.notifications
|
31
29
|
end
|
32
30
|
|
33
|
-
# Internal: Local helper.
|
34
31
|
def check_ins
|
35
32
|
self.class.check_ins
|
36
33
|
end
|
@@ -1,20 +1,21 @@
|
|
1
1
|
require 'json'
|
2
2
|
|
3
3
|
module Honeybadger
|
4
|
-
#
|
4
|
+
# @api private
|
5
|
+
# Front end to parsing the backtrace for each notice.
|
5
6
|
class Backtrace
|
6
|
-
#
|
7
|
+
# Handles backtrace parsing line by line.
|
7
8
|
class Line
|
8
|
-
# Backtrace line regexp (optionally allowing leading X: for windows support)
|
9
|
+
# Backtrace line regexp (optionally allowing leading X: for windows support).
|
9
10
|
INPUT_FORMAT = %r{^((?:[a-zA-Z]:)?[^:]+):(\d+)(?::in `([^']+)')?$}.freeze
|
10
11
|
|
11
|
-
# The file portion of the line (such as app/models/user.rb)
|
12
|
+
# The file portion of the line (such as app/models/user.rb).
|
12
13
|
attr_reader :file
|
13
14
|
|
14
|
-
# The line number portion of the line
|
15
|
+
# The line number portion of the line.
|
15
16
|
attr_reader :number
|
16
17
|
|
17
|
-
# The method of the line (such as index)
|
18
|
+
# The method of the line (such as index).
|
18
19
|
attr_reader :method
|
19
20
|
|
20
21
|
# Filtered representations
|
@@ -22,9 +23,9 @@ module Honeybadger
|
|
22
23
|
|
23
24
|
# Parses a single line of a given backtrace
|
24
25
|
#
|
25
|
-
# unparsed_line
|
26
|
+
# @param [String] unparsed_line The raw line from +caller+ or some backtrace.
|
26
27
|
#
|
27
|
-
#
|
28
|
+
# @return The parsed backtrace line.
|
28
29
|
def self.parse(unparsed_line, opts = {})
|
29
30
|
filters = opts[:filters] || []
|
30
31
|
filtered_line = filters.reduce(unparsed_line) do |line, proc|
|
data/lib/honeybadger/cli.rb
CHANGED
@@ -53,10 +53,10 @@ module Honeybadger
|
|
53
53
|
|
54
54
|
private
|
55
55
|
|
56
|
-
#
|
56
|
+
# Detects the Heroku app name from GIT.
|
57
57
|
#
|
58
|
-
# prompt_on_default
|
59
|
-
#
|
58
|
+
# @param [Boolean] prompt_on_default If a single remote is discoverd,
|
59
|
+
# should we prompt the user before returning it?
|
60
60
|
#
|
61
61
|
# Returns the String app name if detected, otherwise nil.
|
62
62
|
def detect_heroku_app(prompt_on_default = true)
|
data/lib/honeybadger/cli/test.rb
CHANGED
@@ -141,7 +141,7 @@ module Honeybadger
|
|
141
141
|
r.disable_clear_and_finalize = true
|
142
142
|
r.clear!
|
143
143
|
r.draw do
|
144
|
-
match 'verify' => 'honeybadger/test#verify', :as =>
|
144
|
+
match 'verify' => 'honeybadger/test#verify', :as => "verify_#{SecureRandom.hex}", :via => :get
|
145
145
|
end
|
146
146
|
::Rails.application.routes_reloader.paths.each{ |path| load(path) }
|
147
147
|
::ActiveSupport.on_load(:action_controller) { r.finalize! }
|
data/lib/honeybadger/config.rb
CHANGED
@@ -13,9 +13,9 @@ require 'honeybadger/util/revision'
|
|
13
13
|
require 'honeybadger/logging'
|
14
14
|
|
15
15
|
module Honeybadger
|
16
|
-
#
|
17
|
-
#
|
18
|
-
#
|
16
|
+
# @api private
|
17
|
+
# The Config class is used to manage Honeybadger's initialization and
|
18
|
+
# configuration.
|
19
19
|
class Config
|
20
20
|
extend Forwardable
|
21
21
|
|
@@ -125,6 +125,7 @@ module Honeybadger
|
|
125
125
|
|
126
126
|
# Internal Helpers
|
127
127
|
|
128
|
+
|
128
129
|
def logger
|
129
130
|
init_logging! unless @logger
|
130
131
|
@logger
|
@@ -241,9 +242,6 @@ module Honeybadger
|
|
241
242
|
includes_token?(self[:plugins], name)
|
242
243
|
end
|
243
244
|
|
244
|
-
# Match the project root.
|
245
|
-
#
|
246
|
-
# Returns Regexp matching the project root in a file string.
|
247
245
|
def root_regexp
|
248
246
|
return @root_regexp if @root_regexp
|
249
247
|
return nil if @no_root
|
@@ -285,19 +283,12 @@ module Honeybadger
|
|
285
283
|
set(:revision, Util::Revision.detect(self[:root]))
|
286
284
|
end
|
287
285
|
|
288
|
-
# Optional path to honeybadger.log log file.
|
289
|
-
#
|
290
|
-
# Returns the Pathname log path if a log path was specified.
|
291
286
|
def log_path
|
292
287
|
return if log_stdout?
|
293
288
|
return if !self[:'logging.path']
|
294
289
|
locate_absolute_path(self[:'logging.path'], self[:root])
|
295
290
|
end
|
296
291
|
|
297
|
-
# Path to honeybadger.yml configuration file; this should be the
|
298
|
-
# root directory if no path was specified.
|
299
|
-
#
|
300
|
-
# Returns the Pathname configuration path.
|
301
292
|
def config_path
|
302
293
|
config_paths.first
|
303
294
|
end
|
@@ -370,12 +361,8 @@ module Honeybadger
|
|
370
361
|
@logger = Logging::ConfigLogger.new(self, build_logger)
|
371
362
|
end
|
372
363
|
|
373
|
-
#
|
374
|
-
#
|
375
|
-
# obj - The Array object, if present.
|
376
|
-
# value - The value which may exist within Array obj.
|
377
|
-
#
|
378
|
-
# Returns true or false.
|
364
|
+
# Takes an Array and a value and returns true if the value exists in the
|
365
|
+
# array in String or Symbol form, otherwise false.
|
379
366
|
def includes_token?(obj, value)
|
380
367
|
return false unless obj.kind_of?(Array)
|
381
368
|
obj.map(&:to_sym).include?(value.to_sym)
|
@@ -17,6 +17,8 @@ module Honeybadger
|
|
17
17
|
'ActionController::ParameterMissing',
|
18
18
|
'ActiveRecord::RecordNotFound',
|
19
19
|
'ActionController::UnknownAction',
|
20
|
+
'Rack::QueryParser::ParameterTypeError',
|
21
|
+
'Rack::QueryParser::InvalidParameterError',
|
20
22
|
'CGI::Session::CookieStore::TamperedWithCookie',
|
21
23
|
'Mongoid::Errors::DocumentNotFound',
|
22
24
|
'Sinatra::NotFound'].map(&:freeze).freeze
|
data/lib/honeybadger/const.rb
CHANGED
@@ -1,12 +1,20 @@
|
|
1
1
|
require 'honeybadger/version'
|
2
2
|
|
3
3
|
module Honeybadger
|
4
|
-
# Autoloading allows middleware classes to be referenced in applications
|
5
|
-
# which include the optional Rack dependency without explicitly requiring
|
6
|
-
# these files.
|
7
4
|
module Rack
|
5
|
+
# Autoloading allows middleware classes to be referenced in applications
|
6
|
+
# which include the optional Rack dependency without explicitly requiring
|
7
|
+
# these files.
|
8
8
|
autoload :ErrorNotifier, 'honeybadger/rack/error_notifier'
|
9
9
|
autoload :UserFeedback, 'honeybadger/rack/user_feedback'
|
10
10
|
autoload :UserInformer, 'honeybadger/rack/user_informer'
|
11
11
|
end
|
12
|
+
|
13
|
+
# @api private
|
14
|
+
module Plugins
|
15
|
+
end
|
16
|
+
|
17
|
+
# @api private
|
18
|
+
module Util
|
19
|
+
end
|
12
20
|
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'honeybadger/conversions'
|
2
2
|
|
3
3
|
module Honeybadger
|
4
|
+
# @api private
|
4
5
|
class ContextManager
|
5
6
|
include Conversions
|
6
7
|
|
@@ -17,7 +18,8 @@ module Honeybadger
|
|
17
18
|
_initialize
|
18
19
|
end
|
19
20
|
|
20
|
-
# Internal
|
21
|
+
# Internal helpers
|
22
|
+
|
21
23
|
|
22
24
|
def set_context(hash)
|
23
25
|
@mutex.synchronize do
|
@@ -1,12 +1,13 @@
|
|
1
1
|
module Honeybadger
|
2
|
+
# @api private
|
2
3
|
module Conversions
|
3
4
|
module_function
|
4
5
|
|
5
|
-
#
|
6
|
+
# Convert context into a Hash.
|
6
7
|
#
|
7
|
-
# object
|
8
|
+
# @param [Object] object The context object.
|
8
9
|
#
|
9
|
-
#
|
10
|
+
# @return [Hash] The hash context.
|
10
11
|
def Context(object)
|
11
12
|
object = object.to_honeybadger_context if object.respond_to?(:to_honeybadger_context)
|
12
13
|
Hash(object)
|
@@ -9,6 +9,9 @@ module Honeybadger
|
|
9
9
|
def build_with_honeybadger(*args, &block)
|
10
10
|
configure_honeybadger
|
11
11
|
install_honeybadger
|
12
|
+
# Sinatra is a special case. Sinatra starts the web application in an at_exit
|
13
|
+
# handler. And, since we require sinatra before requiring HB, the only way to
|
14
|
+
# setup our at_exit callback is in the sinatra build callback honeybadger/init/sinatra.rb
|
12
15
|
Honeybadger.install_at_exit_callback
|
13
16
|
build_without_honeybadger(*args, &block)
|
14
17
|
end
|
data/lib/honeybadger/logging.rb
CHANGED
@@ -4,13 +4,14 @@ require 'delegate'
|
|
4
4
|
require 'forwardable'
|
5
5
|
|
6
6
|
module Honeybadger
|
7
|
+
# @api private
|
7
8
|
module Logging
|
8
9
|
PREFIX = '** [Honeybadger] '.freeze
|
9
10
|
|
10
|
-
#
|
11
|
-
#
|
12
|
-
#
|
13
|
-
#
|
11
|
+
# Logging helper methods. Requires a Honeybadger::Config @config instance
|
12
|
+
# variable to exist and/or #logger to be defined. Each method is
|
13
|
+
# defined/block captured in this module rather than delegating to the
|
14
|
+
# logger directly to avoid extra object allocation.
|
14
15
|
module Helper
|
15
16
|
private
|
16
17
|
def debug(msg = nil)
|
data/lib/honeybadger/notice.rb
CHANGED
@@ -11,6 +11,7 @@ require 'honeybadger/util/request_hash'
|
|
11
11
|
require 'honeybadger/util/request_payload'
|
12
12
|
|
13
13
|
module Honeybadger
|
14
|
+
# @api private
|
14
15
|
NOTIFIER = {
|
15
16
|
name: 'honeybadger-ruby'.freeze,
|
16
17
|
url: 'https://github.com/honeybadger-io/honeybadger-ruby'.freeze,
|
@@ -18,21 +19,27 @@ module Honeybadger
|
|
18
19
|
language: 'ruby'.freeze
|
19
20
|
}.freeze
|
20
21
|
|
21
|
-
#
|
22
|
+
# @api private
|
23
|
+
# Substitution for gem root in backtrace lines.
|
22
24
|
GEM_ROOT = '[GEM_ROOT]'.freeze
|
23
25
|
|
24
|
-
#
|
26
|
+
# @api private
|
27
|
+
# Substitution for project root in backtrace lines.
|
25
28
|
PROJECT_ROOT = '[PROJECT_ROOT]'.freeze
|
26
29
|
|
27
|
-
#
|
30
|
+
# @api private
|
31
|
+
# Empty String (used for equality comparisons and assignment).
|
28
32
|
STRING_EMPTY = ''.freeze
|
29
33
|
|
30
|
-
#
|
34
|
+
# @api private
|
35
|
+
# A Regexp which matches non-blank characters.
|
31
36
|
NOT_BLANK = /\S/.freeze
|
32
37
|
|
33
|
-
#
|
38
|
+
# @api private
|
39
|
+
# Matches lines beginning with ./
|
34
40
|
RELATIVE_ROOT = Regexp.new('^\.\/').freeze
|
35
41
|
|
42
|
+
# @api private
|
36
43
|
MAX_EXCEPTION_CAUSES = 5
|
37
44
|
|
38
45
|
class Notice
|
@@ -40,74 +47,79 @@ module Honeybadger
|
|
40
47
|
|
41
48
|
include Conversions
|
42
49
|
|
43
|
-
#
|
50
|
+
# @api private
|
51
|
+
# The String character used to split tag strings.
|
44
52
|
TAG_SEPERATOR = ','.freeze
|
45
53
|
|
46
|
-
#
|
54
|
+
# @api private
|
55
|
+
# The Regexp used to strip invalid characters from individual tags.
|
47
56
|
TAG_SANITIZER = /[^\w]/.freeze
|
48
57
|
|
49
|
-
#
|
50
|
-
#
|
58
|
+
# The unique ID of this notice which can be used to reference the error in
|
59
|
+
# Honeybadger.
|
51
60
|
attr_reader :id
|
52
61
|
|
53
|
-
#
|
62
|
+
# The exception that caused this notice, if any.
|
54
63
|
attr_reader :exception
|
55
64
|
|
56
|
-
#
|
65
|
+
# The exception cause if available.
|
57
66
|
attr_reader :cause
|
58
67
|
|
59
|
-
#
|
68
|
+
# The backtrace from the given exception or hash.
|
60
69
|
attr_reader :backtrace
|
61
70
|
|
62
|
-
#
|
71
|
+
# Custom fingerprint for error, used to group similar errors together.
|
63
72
|
attr_reader :fingerprint
|
64
73
|
|
65
|
-
#
|
74
|
+
# Tags which will be applied to error.
|
66
75
|
attr_reader :tags
|
67
76
|
|
68
|
-
#
|
77
|
+
# The name of the class of error (example: RuntimeError).
|
69
78
|
attr_reader :error_class
|
70
79
|
|
71
|
-
#
|
80
|
+
# The message from the exception, or a general description of the error.
|
72
81
|
attr_reader :error_message
|
73
82
|
|
74
83
|
# Deprecated: Excerpt from source file.
|
75
84
|
attr_reader :source
|
76
85
|
|
77
|
-
#
|
86
|
+
# CGI variables such as HTTP_METHOD.
|
78
87
|
def cgi_data; @request[:cgi_data]; end
|
79
88
|
|
80
|
-
#
|
89
|
+
# A hash of parameters from the query string or post body.
|
81
90
|
def params; @request[:params]; end
|
82
91
|
alias_method :parameters, :params
|
83
92
|
|
84
|
-
#
|
93
|
+
# The component (if any) which was used in this request (usually the controller).
|
85
94
|
def component; @request[:component]; end
|
86
95
|
alias_method :controller, :component
|
87
96
|
|
88
|
-
#
|
97
|
+
# The action (if any) that was called in this request.
|
89
98
|
def action; @request[:action]; end
|
90
99
|
|
91
|
-
#
|
100
|
+
# A hash of session data from the request.
|
92
101
|
def_delegator :@request, :session
|
93
102
|
def session; @request[:session]; end
|
94
103
|
|
95
|
-
#
|
104
|
+
# The URL at which the error occurred (if any).
|
96
105
|
def url; @request[:url]; end
|
97
106
|
|
98
|
-
#
|
107
|
+
# Local variables are extracted from first frame of backtrace.
|
99
108
|
attr_reader :local_variables
|
100
109
|
|
101
|
-
#
|
110
|
+
# The API key used to deliver this notice.
|
102
111
|
attr_reader :api_key
|
103
112
|
|
104
|
-
#
|
113
|
+
# @api private
|
114
|
+
# Cache project path substitutions for backtrace lines.
|
105
115
|
PROJECT_ROOT_CACHE = {}
|
106
116
|
|
107
|
-
#
|
117
|
+
# @api private
|
118
|
+
# Cache gem path substitutions for backtrace lines.
|
108
119
|
GEM_ROOT_CACHE = {}
|
109
120
|
|
110
|
-
#
|
121
|
+
# @api private
|
122
|
+
# A list of backtrace filters to run all the time.
|
111
123
|
BACKTRACE_FILTERS = [
|
112
124
|
lambda { |line|
|
113
125
|
return line unless defined?(Gem)
|
@@ -129,6 +141,7 @@ module Honeybadger
|
|
129
141
|
lambda { |line| line if line !~ %r{lib/honeybadger} }
|
130
142
|
].freeze
|
131
143
|
|
144
|
+
# @api private
|
132
145
|
def initialize(config, opts = {})
|
133
146
|
@now = Time.now.utc
|
134
147
|
@pid = Process.pid
|
@@ -170,9 +183,10 @@ module Honeybadger
|
|
170
183
|
@fingerprint = construct_fingerprint(opts)
|
171
184
|
end
|
172
185
|
|
173
|
-
#
|
186
|
+
# @api private
|
187
|
+
# Template used to create JSON payload.
|
174
188
|
#
|
175
|
-
#
|
189
|
+
# @return [Hash] JSON representation of notice.
|
176
190
|
def as_json(*args)
|
177
191
|
@request[:context] = s(context)
|
178
192
|
@request[:local_variables] = local_variables if local_variables
|
@@ -202,22 +216,21 @@ module Honeybadger
|
|
202
216
|
}
|
203
217
|
end
|
204
218
|
|
205
|
-
#
|
219
|
+
# Converts the notice to JSON.
|
206
220
|
#
|
207
|
-
#
|
221
|
+
# @return [Hash] The JSON representation of the notice.
|
208
222
|
def to_json(*a)
|
209
223
|
::JSON.generate(as_json(*a))
|
210
224
|
end
|
211
225
|
|
212
|
-
#
|
213
|
-
#
|
214
|
-
# method - The given key for an attribute.
|
215
|
-
#
|
216
|
-
# Examples
|
226
|
+
# Allows properties to be accessed using a hash-like syntax.
|
217
227
|
#
|
228
|
+
# @example
|
218
229
|
# notice[:error_message]
|
219
230
|
#
|
220
|
-
#
|
231
|
+
# @param [Symbol] method The given key for an attribute.
|
232
|
+
#
|
233
|
+
# @return [Object] The attribute value.
|
221
234
|
def [](method)
|
222
235
|
case method
|
223
236
|
when :request
|
@@ -227,7 +240,8 @@ module Honeybadger
|
|
227
240
|
end
|
228
241
|
end
|
229
242
|
|
230
|
-
#
|
243
|
+
# @api private
|
244
|
+
# Determines if this notice should be ignored.
|
231
245
|
def ignore?
|
232
246
|
ignore_by_origin? || ignore_by_class? || ignore_by_callbacks?
|
233
247
|
end
|
@@ -280,7 +294,7 @@ module Honeybadger
|
|
280
294
|
end
|
281
295
|
end
|
282
296
|
|
283
|
-
#
|
297
|
+
# Determines if error class should be ignored.
|
284
298
|
#
|
285
299
|
# ignored_class_name - The name of the ignored class. May be a
|
286
300
|
# string or regexp (optional).
|
@@ -310,7 +324,7 @@ module Honeybadger
|
|
310
324
|
Util::RequestHash.from_env(rack_env)
|
311
325
|
end
|
312
326
|
|
313
|
-
#
|
327
|
+
# Construct the request object with data from various sources.
|
314
328
|
#
|
315
329
|
# Returns Request.
|
316
330
|
def construct_request_hash(config, opts)
|
@@ -324,7 +338,7 @@ module Honeybadger
|
|
324
338
|
Util::RequestPayload.build(request)
|
325
339
|
end
|
326
340
|
|
327
|
-
#
|
341
|
+
# Get optional context from exception.
|
328
342
|
#
|
329
343
|
# Returns the Hash context.
|
330
344
|
def exception_context(exception)
|
@@ -378,7 +392,7 @@ module Honeybadger
|
|
378
392
|
Util::Sanitizer.sanitize(data)
|
379
393
|
end
|
380
394
|
|
381
|
-
#
|
395
|
+
# Fetch local variables from first frame of backtrace.
|
382
396
|
#
|
383
397
|
# exception - The Exception containing the bindings stack.
|
384
398
|
#
|
@@ -412,14 +426,14 @@ module Honeybadger
|
|
412
426
|
request_sanitizer.sanitize(result_hash)
|
413
427
|
end
|
414
428
|
|
415
|
-
#
|
429
|
+
# Should local variables be sent?
|
416
430
|
#
|
417
431
|
# Returns true to send local_variables.
|
418
432
|
def send_local_variables?(config)
|
419
433
|
config[:'exceptions.local_variables']
|
420
434
|
end
|
421
435
|
|
422
|
-
#
|
436
|
+
# Parse Backtrace from exception backtrace.
|
423
437
|
#
|
424
438
|
# backtrace - The Array backtrace from exception.
|
425
439
|
#
|
@@ -433,7 +447,7 @@ module Honeybadger
|
|
433
447
|
)
|
434
448
|
end
|
435
449
|
|
436
|
-
#
|
450
|
+
# Unwrap the exception so that original exception is ignored or
|
437
451
|
# reported.
|
438
452
|
#
|
439
453
|
# exception - The exception which was rescued.
|
@@ -444,7 +458,7 @@ module Honeybadger
|
|
444
458
|
exception_cause(exception) || exception
|
445
459
|
end
|
446
460
|
|
447
|
-
#
|
461
|
+
# Fetch cause from exception.
|
448
462
|
#
|
449
463
|
# exception - Exception to fetch cause from.
|
450
464
|
#
|
@@ -460,7 +474,7 @@ module Honeybadger
|
|
460
474
|
end
|
461
475
|
end
|
462
476
|
|
463
|
-
#
|
477
|
+
# Create a list of causes.
|
464
478
|
#
|
465
479
|
# cause - The first cause to unwrap.
|
466
480
|
#
|
@@ -489,7 +503,7 @@ module Honeybadger
|
|
489
503
|
rack_env && Array(rack_env['action_dispatch.parameter_filter']) or []
|
490
504
|
end
|
491
505
|
|
492
|
-
#
|
506
|
+
# This is how much Honeybadger cares about Rails developers. :)
|
493
507
|
#
|
494
508
|
# Some Rails projects include ActionDispatch::TestProcess globally for the
|
495
509
|
# use of `fixture_file_upload` in tests. This is a bad practice because it
|
@@ -498,7 +512,7 @@ module Honeybadger
|
|
498
512
|
#
|
499
513
|
# When you call #session on any object which had previously defined it
|
500
514
|
# (such as OpenStruct), that newly defined method calls #session on
|
501
|
-
#
|
515
|
+
# +@request+ (defined in `ActionDispatch::TestProcess`), and if +@request+
|
502
516
|
# doesn't exist in that object, it calls #session *again* on `nil`, which
|
503
517
|
# also inherited it from Object, resulting in a SystemStackError.
|
504
518
|
#
|