airbrake-ruby 2.9.0 → 2.10.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/airbrake-ruby.rb +40 -18
- data/lib/airbrake-ruby/async_sender.rb +0 -6
- data/lib/airbrake-ruby/backtrace.rb +0 -10
- data/lib/airbrake-ruby/code_hunk.rb +0 -4
- data/lib/airbrake-ruby/config.rb +23 -22
- data/lib/airbrake-ruby/config/validator.rb +0 -10
- data/lib/airbrake-ruby/file_cache.rb +0 -6
- data/lib/airbrake-ruby/filter_chain.rb +0 -5
- data/lib/airbrake-ruby/filters/context_filter.rb +1 -0
- data/lib/airbrake-ruby/filters/dependency_filter.rb +31 -0
- data/lib/airbrake-ruby/filters/exception_attributes_filter.rb +45 -0
- data/lib/airbrake-ruby/filters/gem_root_filter.rb +2 -3
- data/lib/airbrake-ruby/filters/keys_blacklist.rb +1 -2
- data/lib/airbrake-ruby/filters/keys_filter.rb +9 -14
- data/lib/airbrake-ruby/filters/keys_whitelist.rb +0 -2
- data/lib/airbrake-ruby/filters/root_directory_filter.rb +2 -3
- data/lib/airbrake-ruby/filters/system_exit_filter.rb +2 -3
- data/lib/airbrake-ruby/filters/thread_filter.rb +2 -4
- data/lib/airbrake-ruby/nested_exception.rb +0 -2
- data/lib/airbrake-ruby/notice.rb +6 -44
- data/lib/airbrake-ruby/notifier.rb +4 -40
- data/lib/airbrake-ruby/promise.rb +0 -6
- data/lib/airbrake-ruby/response.rb +0 -4
- data/lib/airbrake-ruby/sync_sender.rb +0 -4
- data/lib/airbrake-ruby/version.rb +1 -3
- data/spec/airbrake_spec.rb +71 -140
- data/spec/async_sender_spec.rb +9 -0
- data/spec/config_spec.rb +4 -0
- data/spec/filters/dependency_filter_spec.rb +16 -0
- data/spec/filters/exception_attributes_filter_spec.rb +65 -0
- data/spec/filters/keys_whitelist_spec.rb +17 -23
- data/spec/notice_spec.rb +111 -69
- data/spec/notifier_spec.rb +304 -495
- data/spec/response_spec.rb +82 -0
- data/spec/sync_sender_spec.rb +31 -14
- metadata +10 -2
@@ -1,36 +1,29 @@
|
|
1
1
|
module Airbrake
|
2
2
|
class Config
|
3
|
-
##
|
4
3
|
# Validates values of {Airbrake::Config} options.
|
5
4
|
#
|
6
5
|
# @api private
|
7
6
|
# @since v1.5.0
|
8
7
|
class Validator
|
9
|
-
##
|
10
8
|
# @return [String]
|
11
9
|
REQUIRED_KEY_MSG = ':project_key is required'.freeze
|
12
10
|
|
13
|
-
##
|
14
11
|
# @return [String]
|
15
12
|
REQUIRED_ID_MSG = ':project_id is required'.freeze
|
16
13
|
|
17
|
-
##
|
18
14
|
# @return [String]
|
19
15
|
WRONG_ENV_TYPE_MSG = "the 'environment' option must be configured " \
|
20
16
|
"with a Symbol (or String), but '%s' was provided: " \
|
21
17
|
'%s'.freeze
|
22
18
|
|
23
|
-
##
|
24
19
|
# @return [Array<Class>] the list of allowed types to configure the
|
25
20
|
# environment option
|
26
21
|
VALID_ENV_TYPES = [NilClass, String, Symbol].freeze
|
27
22
|
|
28
|
-
##
|
29
23
|
# @return [String] error message, if validator was able to find any errors
|
30
24
|
# in the config
|
31
25
|
attr_reader :error_message
|
32
26
|
|
33
|
-
##
|
34
27
|
# Validates given config and stores error message, if any errors were
|
35
28
|
# found.
|
36
29
|
#
|
@@ -40,7 +33,6 @@ module Airbrake
|
|
40
33
|
@error_message = nil
|
41
34
|
end
|
42
35
|
|
43
|
-
##
|
44
36
|
# @return [Boolean]
|
45
37
|
def valid_project_id?
|
46
38
|
valid = @config.project_id.to_i > 0
|
@@ -48,7 +40,6 @@ module Airbrake
|
|
48
40
|
valid
|
49
41
|
end
|
50
42
|
|
51
|
-
##
|
52
43
|
# @return [Boolean]
|
53
44
|
def valid_project_key?
|
54
45
|
valid = @config.project_key.is_a?(String) && !@config.project_key.empty?
|
@@ -56,7 +47,6 @@ module Airbrake
|
|
56
47
|
valid
|
57
48
|
end
|
58
49
|
|
59
|
-
##
|
60
50
|
# @return [Boolean]
|
61
51
|
def valid_environment?
|
62
52
|
environment = @config.environment
|
@@ -1,19 +1,15 @@
|
|
1
1
|
module Airbrake
|
2
|
-
##
|
3
2
|
# Extremely simple global cache.
|
4
3
|
#
|
5
4
|
# @api private
|
6
5
|
# @since v2.4.1
|
7
6
|
module FileCache
|
8
|
-
##
|
9
7
|
# @return [Integer]
|
10
8
|
MAX_SIZE = 50
|
11
9
|
|
12
|
-
##
|
13
10
|
# @return [Mutex]
|
14
11
|
MUTEX = Mutex.new
|
15
12
|
|
16
|
-
##
|
17
13
|
# Associates the value given by +value+ with the key given by +key+. Deletes
|
18
14
|
# entries that exceed +MAX_SIZE+.
|
19
15
|
#
|
@@ -27,7 +23,6 @@ module Airbrake
|
|
27
23
|
end
|
28
24
|
end
|
29
25
|
|
30
|
-
##
|
31
26
|
# Retrieve an object from the cache.
|
32
27
|
#
|
33
28
|
# @param [Object] key
|
@@ -38,7 +33,6 @@ module Airbrake
|
|
38
33
|
end
|
39
34
|
end
|
40
35
|
|
41
|
-
##
|
42
36
|
# Checks whether the cache is empty. Needed only for the test suite.
|
43
37
|
#
|
44
38
|
# @return [Boolean]
|
@@ -1,5 +1,4 @@
|
|
1
1
|
module Airbrake
|
2
|
-
##
|
3
2
|
# Represents the mechanism for filtering notices. Defines a few default
|
4
3
|
# filters.
|
5
4
|
#
|
@@ -7,7 +6,6 @@ module Airbrake
|
|
7
6
|
# @api private
|
8
7
|
# @since v1.0.0
|
9
8
|
class FilterChain
|
10
|
-
##
|
11
9
|
# @return [Array<Class>] filters to be executed first
|
12
10
|
DEFAULT_FILTERS = [
|
13
11
|
Airbrake::Filters::SystemExitFilter,
|
@@ -17,7 +15,6 @@ module Airbrake
|
|
17
15
|
# Airbrake::Filters::ThreadFilter
|
18
16
|
].freeze
|
19
17
|
|
20
|
-
##
|
21
18
|
# @return [Integer]
|
22
19
|
DEFAULT_WEIGHT = 0
|
23
20
|
|
@@ -26,7 +23,6 @@ module Airbrake
|
|
26
23
|
DEFAULT_FILTERS.each { |f| add_filter(f.new) }
|
27
24
|
end
|
28
25
|
|
29
|
-
##
|
30
26
|
# Adds a filter to the filter chain. Sorts filters by weight.
|
31
27
|
#
|
32
28
|
# @param [#call] filter The filter object (proc, class, module, etc)
|
@@ -37,7 +33,6 @@ module Airbrake
|
|
37
33
|
end.reverse!
|
38
34
|
end
|
39
35
|
|
40
|
-
##
|
41
36
|
# Applies all the filters in the filter chain to the given notice. Does not
|
42
37
|
# filter ignored notices.
|
43
38
|
#
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Airbrake
|
2
|
+
module Filters
|
3
|
+
# Attaches loaded dependencies to the notice object.
|
4
|
+
#
|
5
|
+
# @api private
|
6
|
+
# @since v2.10.0
|
7
|
+
class DependencyFilter
|
8
|
+
def initialize
|
9
|
+
@weight = 117
|
10
|
+
end
|
11
|
+
|
12
|
+
# @macro call_filter
|
13
|
+
def call(notice)
|
14
|
+
deps = {}
|
15
|
+
Gem.loaded_specs.map.with_object(deps) do |(name, spec), h|
|
16
|
+
h[name] = "#{spec.version}#{git_version(spec)}"
|
17
|
+
end
|
18
|
+
|
19
|
+
notice[:context][:versions] = {} unless notice[:context].key?(:versions)
|
20
|
+
notice[:context][:versions][:dependencies] = deps
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def git_version(spec)
|
26
|
+
return unless spec.respond_to?(:git_version) || spec.git_version
|
27
|
+
spec.git_version.to_s
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module Airbrake
|
2
|
+
module Filters
|
3
|
+
# ExceptionAttributesFilter attempts to call `#to_airbrake` on the stashed
|
4
|
+
# exception and attaches returned data to the notice object.
|
5
|
+
#
|
6
|
+
# @api private
|
7
|
+
# @since v2.10.0
|
8
|
+
class ExceptionAttributesFilter
|
9
|
+
def initialize(logger)
|
10
|
+
@logger = logger
|
11
|
+
@weight = 118
|
12
|
+
end
|
13
|
+
|
14
|
+
# @macro call_filter
|
15
|
+
def call(notice)
|
16
|
+
exception = notice.stash[:exception]
|
17
|
+
return unless exception.respond_to?(:to_airbrake)
|
18
|
+
|
19
|
+
attributes = nil
|
20
|
+
begin
|
21
|
+
attributes = exception.to_airbrake
|
22
|
+
rescue StandardError => ex
|
23
|
+
@logger.error(
|
24
|
+
"#{LOG_LABEL} #{exception.class}#to_airbrake failed. #{ex.class}: #{ex}"
|
25
|
+
)
|
26
|
+
end
|
27
|
+
|
28
|
+
unless attributes.is_a?(Hash)
|
29
|
+
@logger.error(
|
30
|
+
"#{LOG_LABEL} #{self.class}: wanted Hash, got #{attributes.class}"
|
31
|
+
)
|
32
|
+
return
|
33
|
+
end
|
34
|
+
|
35
|
+
attributes.each do |key, attrs|
|
36
|
+
if notice[key]
|
37
|
+
notice[key].merge!(attrs)
|
38
|
+
else
|
39
|
+
notice[key] = attrs
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -1,13 +1,11 @@
|
|
1
1
|
module Airbrake
|
2
2
|
module Filters
|
3
|
-
##
|
4
3
|
# Replaces paths to gems with a placeholder.
|
4
|
+
# @api private
|
5
5
|
class GemRootFilter
|
6
|
-
##
|
7
6
|
# @return [String]
|
8
7
|
GEM_ROOT_LABEL = '/GEM_ROOT'.freeze
|
9
8
|
|
10
|
-
##
|
11
9
|
# @return [Integer]
|
12
10
|
attr_reader :weight
|
13
11
|
|
@@ -15,6 +13,7 @@ module Airbrake
|
|
15
13
|
@weight = 120
|
16
14
|
end
|
17
15
|
|
16
|
+
# @macro call_filter
|
18
17
|
def call(notice)
|
19
18
|
return unless defined?(Gem)
|
20
19
|
|
@@ -1,6 +1,5 @@
|
|
1
1
|
module Airbrake
|
2
2
|
module Filters
|
3
|
-
##
|
4
3
|
# A default Airbrake notice filter. Filters only specific keys listed in the
|
5
4
|
# list of parameters in the payload of a notice.
|
6
5
|
#
|
@@ -26,6 +25,7 @@ module Airbrake
|
|
26
25
|
#
|
27
26
|
# @see KeysWhitelist
|
28
27
|
# @see KeysFilter
|
28
|
+
# @api private
|
29
29
|
class KeysBlacklist
|
30
30
|
include KeysFilter
|
31
31
|
|
@@ -34,7 +34,6 @@ module Airbrake
|
|
34
34
|
@weight = -110
|
35
35
|
end
|
36
36
|
|
37
|
-
##
|
38
37
|
# @return [Boolean] true if the key matches at least one pattern, false
|
39
38
|
# otherwise
|
40
39
|
def should_filter?(key)
|
@@ -1,6 +1,7 @@
|
|
1
1
|
module Airbrake
|
2
|
+
# Namespace for all standard filters. Custom filters can also go under this
|
3
|
+
# namespace.
|
2
4
|
module Filters
|
3
|
-
##
|
4
5
|
# This is a filter helper that endows a class ability to filter notices'
|
5
6
|
# payload based on the return value of the +should_filter?+ method that a
|
6
7
|
# class that includes this module must implement.
|
@@ -8,31 +9,26 @@ module Airbrake
|
|
8
9
|
# @see Notice
|
9
10
|
# @see KeysWhitelist
|
10
11
|
# @see KeysBlacklist
|
12
|
+
# @api private
|
11
13
|
module KeysFilter
|
12
|
-
##
|
13
14
|
# @return [String] The label to replace real values of filtered payload
|
14
15
|
FILTERED = '[Filtered]'.freeze
|
15
16
|
|
16
|
-
##
|
17
17
|
# @return [Array<String,Symbol,Regexp>] the array of classes instances of
|
18
18
|
# which can compared with payload keys
|
19
19
|
VALID_PATTERN_CLASSES = [String, Symbol, Regexp].freeze
|
20
20
|
|
21
|
-
##
|
22
21
|
# @return [Array<Symbol>] parts of a Notice's payload that can be modified
|
23
22
|
# by blacklist/whitelist filters
|
24
23
|
FILTERABLE_KEYS = %i[environment session params].freeze
|
25
24
|
|
26
|
-
##
|
27
25
|
# @return [Array<Symbol>] parts of a Notice's *context* payload that can
|
28
26
|
# be modified by blacklist/whitelist filters
|
29
27
|
FILTERABLE_CONTEXT_KEYS = %i[user headers].freeze
|
30
28
|
|
31
|
-
##
|
32
29
|
# @return [Integer]
|
33
30
|
attr_reader :weight
|
34
31
|
|
35
|
-
##
|
36
32
|
# Creates a new KeysBlacklist or KeysWhitelist filter that uses the given
|
37
33
|
# +patterns+ for filtering a notice's payload.
|
38
34
|
#
|
@@ -44,13 +40,13 @@ module Airbrake
|
|
44
40
|
@valid_patterns = false
|
45
41
|
end
|
46
42
|
|
47
|
-
|
48
|
-
#
|
49
|
-
#
|
43
|
+
# @!macro call_filter
|
44
|
+
# This is a mandatory method required by any filter integrated with
|
45
|
+
# FilterChain.
|
50
46
|
#
|
51
|
-
#
|
52
|
-
#
|
53
|
-
#
|
47
|
+
# @param [Notice] notice the notice to be filtered
|
48
|
+
# @return [void]
|
49
|
+
# @see FilterChain
|
54
50
|
def call(notice)
|
55
51
|
unless @valid_patterns
|
56
52
|
eval_proc_patterns!
|
@@ -64,7 +60,6 @@ module Airbrake
|
|
64
60
|
filter_url(notice)
|
65
61
|
end
|
66
62
|
|
67
|
-
##
|
68
63
|
# @raise [NotImplementedError] if called directly
|
69
64
|
def should_filter?(_key)
|
70
65
|
raise NotImplementedError, 'method must be implemented in the included class'
|
@@ -1,6 +1,5 @@
|
|
1
1
|
module Airbrake
|
2
2
|
module Filters
|
3
|
-
##
|
4
3
|
# A default Airbrake notice filter. Filters everything in the payload of a
|
5
4
|
# notice, but specified keys.
|
6
5
|
#
|
@@ -34,7 +33,6 @@ module Airbrake
|
|
34
33
|
@weight = -100
|
35
34
|
end
|
36
35
|
|
37
|
-
##
|
38
36
|
# @return [Boolean] true if the key doesn't match any pattern, false
|
39
37
|
# otherwise.
|
40
38
|
def should_filter?(key)
|
@@ -1,13 +1,11 @@
|
|
1
1
|
module Airbrake
|
2
2
|
module Filters
|
3
|
-
##
|
4
3
|
# Replaces root directory with a label.
|
4
|
+
# @api private
|
5
5
|
class RootDirectoryFilter
|
6
|
-
##
|
7
6
|
# @return [String]
|
8
7
|
PROJECT_ROOT_LABEL = '/PROJECT_ROOT'.freeze
|
9
8
|
|
10
|
-
##
|
11
9
|
# @return [Integer]
|
12
10
|
attr_reader :weight
|
13
11
|
|
@@ -16,6 +14,7 @@ module Airbrake
|
|
16
14
|
@weight = 100
|
17
15
|
end
|
18
16
|
|
17
|
+
# @macro call_filter
|
19
18
|
def call(notice)
|
20
19
|
notice[:errors].each do |error|
|
21
20
|
error[:backtrace].each do |frame|
|
@@ -1,13 +1,11 @@
|
|
1
1
|
module Airbrake
|
2
2
|
module Filters
|
3
|
-
##
|
4
3
|
# Skip over SystemExit exceptions, because they're just noise.
|
4
|
+
# @api private
|
5
5
|
class SystemExitFilter
|
6
|
-
##
|
7
6
|
# @return [String]
|
8
7
|
SYSTEM_EXIT_TYPE = 'SystemExit'.freeze
|
9
8
|
|
10
|
-
##
|
11
9
|
# @return [Integer]
|
12
10
|
attr_reader :weight
|
13
11
|
|
@@ -15,6 +13,7 @@ module Airbrake
|
|
15
13
|
@weight = 130
|
16
14
|
end
|
17
15
|
|
16
|
+
# @macro call_filter
|
18
17
|
def call(notice)
|
19
18
|
return if notice[:errors].none? { |error| error[:type] == SYSTEM_EXIT_TYPE }
|
20
19
|
notice.ignore!
|
@@ -1,14 +1,12 @@
|
|
1
1
|
module Airbrake
|
2
2
|
module Filters
|
3
|
-
##
|
4
3
|
# Attaches thread & fiber local variables along with general thread
|
5
4
|
# information.
|
5
|
+
# @api private
|
6
6
|
class ThreadFilter
|
7
|
-
##
|
8
7
|
# @return [Integer]
|
9
8
|
attr_reader :weight
|
10
9
|
|
11
|
-
##
|
12
10
|
# @return [Array<Class>] the list of classes that can be safely converted
|
13
11
|
# to JSON
|
14
12
|
SAFE_CLASSES = [
|
@@ -21,7 +19,6 @@ module Airbrake
|
|
21
19
|
Numeric
|
22
20
|
].freeze
|
23
21
|
|
24
|
-
##
|
25
22
|
# Variables starting with this prefix are not attached to a notice.
|
26
23
|
# @see https://github.com/airbrake/airbrake-ruby/issues/229
|
27
24
|
# @return [String]
|
@@ -31,6 +28,7 @@ module Airbrake
|
|
31
28
|
@weight = 110
|
32
29
|
end
|
33
30
|
|
31
|
+
# @macro call_filter
|
34
32
|
def call(notice)
|
35
33
|
th = Thread.current
|
36
34
|
thread_info = {}
|
@@ -1,12 +1,10 @@
|
|
1
1
|
module Airbrake
|
2
|
-
##
|
3
2
|
# A class that is capable of unwinding nested exceptions and representing them
|
4
3
|
# as JSON-like hash.
|
5
4
|
#
|
6
5
|
# @api private
|
7
6
|
# @since v1.0.4
|
8
7
|
class NestedException
|
9
|
-
##
|
10
8
|
# @return [Integer] the maximum number of nested exceptions that a notice
|
11
9
|
# can unwrap. Exceptions that have a longer cause chain will be ignored
|
12
10
|
MAX_NESTED_EXCEPTIONS = 3
|
data/lib/airbrake-ruby/notice.rb
CHANGED
@@ -1,11 +1,9 @@
|
|
1
1
|
module Airbrake
|
2
|
-
##
|
3
2
|
# Represents a chunk of information that is meant to be either sent to
|
4
3
|
# Airbrake or ignored completely.
|
5
4
|
#
|
6
5
|
# @since v1.0.0
|
7
6
|
class Notice
|
8
|
-
##
|
9
7
|
# @return [Hash{Symbol=>String}] the information about the notifier library
|
10
8
|
NOTIFIER = {
|
11
9
|
name: 'airbrake-ruby'.freeze,
|
@@ -13,7 +11,6 @@ module Airbrake
|
|
13
11
|
url: 'https://github.com/airbrake/airbrake-ruby'.freeze
|
14
12
|
}.freeze
|
15
13
|
|
16
|
-
##
|
17
14
|
# @return [Hash{Symbol=>String,Hash}] the information to be displayed in the
|
18
15
|
# Context tab in the dashboard
|
19
16
|
CONTEXT = {
|
@@ -22,16 +19,13 @@ module Airbrake
|
|
22
19
|
notifier: NOTIFIER
|
23
20
|
}.freeze
|
24
21
|
|
25
|
-
##
|
26
22
|
# @return [Integer] the maxium size of the JSON payload in bytes
|
27
23
|
MAX_NOTICE_SIZE = 64000
|
28
24
|
|
29
|
-
##
|
30
25
|
# @return [Integer] the maximum size of hashes, arrays and strings in the
|
31
26
|
# notice.
|
32
27
|
PAYLOAD_MAX_SIZE = 10000
|
33
28
|
|
34
|
-
##
|
35
29
|
# @return [Array<StandardError>] the list of possible exceptions that might
|
36
30
|
# be raised when an object is converted to JSON
|
37
31
|
JSON_EXCEPTIONS = [
|
@@ -45,25 +39,22 @@ module Airbrake
|
|
45
39
|
# {Airbrake::Notice#[]=}
|
46
40
|
WRITABLE_KEYS = %i[notifier context environment session params].freeze
|
47
41
|
|
48
|
-
##
|
49
42
|
# @return [Array<Symbol>] parts of a Notice's payload that can be modified
|
50
43
|
# by the truncator
|
51
44
|
TRUNCATABLE_KEYS = %i[errors environment session params].freeze
|
52
45
|
|
53
|
-
##
|
54
46
|
# @return [String] the name of the host machine
|
55
47
|
HOSTNAME = Socket.gethostname.freeze
|
56
48
|
|
57
|
-
##
|
58
49
|
# @return [String]
|
59
50
|
DEFAULT_SEVERITY = 'error'.freeze
|
60
51
|
|
61
|
-
##
|
62
52
|
# @since v1.7.0
|
63
53
|
# @return [Hash{Symbol=>Object}] the hash with arbitrary objects to be used
|
64
54
|
# in filters
|
65
55
|
attr_reader :stash
|
66
56
|
|
57
|
+
# @api private
|
67
58
|
def initialize(config, exception, params = {})
|
68
59
|
@config = config
|
69
60
|
|
@@ -78,16 +69,14 @@ module Airbrake
|
|
78
69
|
}
|
79
70
|
@stash = { exception: exception }
|
80
71
|
@truncator = Airbrake::Truncator.new(PAYLOAD_MAX_SIZE)
|
81
|
-
|
82
|
-
extract_custom_attributes(exception)
|
83
72
|
end
|
84
73
|
|
85
|
-
##
|
86
74
|
# Converts the notice to JSON. Calls +to_json+ on each object inside
|
87
75
|
# notice's payload. Truncates notices, JSON representation of which is
|
88
76
|
# bigger than {MAX_NOTICE_SIZE}.
|
89
77
|
#
|
90
78
|
# @return [Hash{String=>String}, nil]
|
79
|
+
# @api private
|
91
80
|
def to_json
|
92
81
|
loop do
|
93
82
|
begin
|
@@ -102,7 +91,6 @@ module Airbrake
|
|
102
91
|
end
|
103
92
|
end
|
104
93
|
|
105
|
-
##
|
106
94
|
# Ignores a notice. Ignored notices never reach the Airbrake dashboard.
|
107
95
|
#
|
108
96
|
# @return [void]
|
@@ -112,7 +100,6 @@ module Airbrake
|
|
112
100
|
@payload = nil
|
113
101
|
end
|
114
102
|
|
115
|
-
##
|
116
103
|
# Checks whether the notice was ignored.
|
117
104
|
#
|
118
105
|
# @return [Boolean]
|
@@ -121,19 +108,17 @@ module Airbrake
|
|
121
108
|
@payload.nil?
|
122
109
|
end
|
123
110
|
|
124
|
-
##
|
125
111
|
# Reads a value from notice's payload.
|
126
|
-
# @return [Object]
|
127
112
|
#
|
113
|
+
# @return [Object]
|
128
114
|
# @raise [Airbrake::Error] if the notice is ignored
|
129
115
|
def [](key)
|
130
116
|
raise_if_ignored
|
131
117
|
@payload[key]
|
132
118
|
end
|
133
119
|
|
134
|
-
|
135
|
-
#
|
136
|
-
# writes.
|
120
|
+
# Writes a value to the payload hash. Restricts unrecognized writes.
|
121
|
+
#
|
137
122
|
# @example
|
138
123
|
# notice[:params][:my_param] = 'foobar'
|
139
124
|
#
|
@@ -161,6 +146,7 @@ module Airbrake
|
|
161
146
|
def context
|
162
147
|
{
|
163
148
|
version: @config.app_version,
|
149
|
+
versions: @config.versions,
|
164
150
|
# We ensure that root_directory is always a String, so it can always be
|
165
151
|
# converted to JSON in a predictable manner (when it's a Pathname and in
|
166
152
|
# Rails environment, it converts to unexpected JSON).
|
@@ -195,29 +181,5 @@ module Airbrake
|
|
195
181
|
|
196
182
|
new_max_size
|
197
183
|
end
|
198
|
-
|
199
|
-
def extract_custom_attributes(exception)
|
200
|
-
return unless exception.respond_to?(:to_airbrake)
|
201
|
-
attributes = nil
|
202
|
-
|
203
|
-
begin
|
204
|
-
attributes = exception.to_airbrake
|
205
|
-
rescue StandardError => ex
|
206
|
-
@config.logger.error(
|
207
|
-
"#{LOG_LABEL} #{exception.class}#to_airbrake failed: #{ex.class}: #{ex}"
|
208
|
-
)
|
209
|
-
end
|
210
|
-
|
211
|
-
return unless attributes
|
212
|
-
|
213
|
-
begin
|
214
|
-
@payload.merge!(attributes)
|
215
|
-
rescue TypeError
|
216
|
-
@config.logger.error(
|
217
|
-
"#{LOG_LABEL} #{exception.class}#to_airbrake failed:" \
|
218
|
-
" #{attributes} must be a Hash"
|
219
|
-
)
|
220
|
-
end
|
221
|
-
end
|
222
184
|
end
|
223
185
|
end
|