honeybadger 3.2.0 → 3.3.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
#
|