airbrake-ruby 1.4.6 → 1.5.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 +4 -4
- data/lib/airbrake-ruby.rb +1 -0
- data/lib/airbrake-ruby/backtrace.rb +8 -4
- data/lib/airbrake-ruby/config.rb +12 -2
- data/lib/airbrake-ruby/config/validator.rb +73 -0
- data/lib/airbrake-ruby/filter_chain.rb +6 -2
- data/lib/airbrake-ruby/filters/keys_filter.rb +6 -2
- data/lib/airbrake-ruby/notice.rb +28 -0
- data/lib/airbrake-ruby/notifier.rb +1 -1
- data/lib/airbrake-ruby/version.rb +1 -1
- data/spec/backtrace_spec.rb +26 -0
- data/spec/config/validator_spec.rb +189 -0
- data/spec/config_spec.rb +16 -0
- data/spec/filter_chain_spec.rb +36 -0
- data/spec/notice_spec.rb +69 -0
- data/spec/notifier_spec.rb +16 -8
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2498350f956db613816b9cf8ae1579a01b0ca940
|
4
|
+
data.tar.gz: 3bafaf42dc712d226ac97b3ad5690f923ff49cc6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 097a7a2681e0d28b020ea43a918b96ed0c89167a96d7b8146f27bac98682d95b61431ffe6eb1d78d278068b6321e4c28f196dec021c8a7fb7ed31c7e6465cc3d
|
7
|
+
data.tar.gz: 3cfdaaf798e0b85835126535434bb10bff78422b1b8890e924cf881b2b3843f0230eea43eaf6efdf0f9e3296941c2e85c217d71d6ed69b8caae3ae94be4baec7
|
data/lib/airbrake-ruby.rb
CHANGED
@@ -26,14 +26,18 @@ module Airbrake
|
|
26
26
|
##
|
27
27
|
# @return [Regexp] the pattern that matches JRuby Java stack frames, such
|
28
28
|
# as org.jruby.ast.NewlineNode.interpret(NewlineNode.java:105)
|
29
|
-
JAVA =
|
30
|
-
(?<function>.+) # Matches 'org.jruby.ast.NewlineNode.interpret
|
29
|
+
JAVA = %r{\A
|
30
|
+
(?<function>.+) # Matches 'org.jruby.ast.NewlineNode.interpret'
|
31
31
|
\(
|
32
|
-
(?<file>
|
32
|
+
(?<file>
|
33
|
+
(?:uri:classloader:/.+(?=:)) # Matches '/META-INF/jruby.home/protocol.rb'
|
34
|
+
|
|
35
|
+
[^:]+ # Matches 'NewlineNode.java'
|
36
|
+
)
|
33
37
|
:?
|
34
38
|
(?<line>\d+)? # Matches '105'
|
35
39
|
\)
|
36
|
-
\z
|
40
|
+
\z}x
|
37
41
|
|
38
42
|
##
|
39
43
|
# @return [Regexp] the pattern that tries to assume what a generic stack
|
data/lib/airbrake-ruby/config.rb
CHANGED
@@ -73,6 +73,8 @@ module Airbrake
|
|
73
73
|
# @param [Hash{Symbol=>Object}] user_config the hash to be used to build the
|
74
74
|
# config
|
75
75
|
def initialize(user_config = {})
|
76
|
+
@validator = Config::Validator.new(self)
|
77
|
+
|
76
78
|
self.proxy = {}
|
77
79
|
self.queue_size = 100
|
78
80
|
self.workers = 1
|
@@ -130,8 +132,16 @@ module Airbrake
|
|
130
132
|
# otherwise
|
131
133
|
def valid?
|
132
134
|
return true if ignored_environment?
|
133
|
-
|
134
|
-
|
135
|
+
|
136
|
+
return false unless @validator.valid_project_id?
|
137
|
+
return false unless @validator.valid_project_key?
|
138
|
+
return false unless @validator.valid_environment?
|
139
|
+
|
140
|
+
true
|
141
|
+
end
|
142
|
+
|
143
|
+
def validation_error_message
|
144
|
+
@validator.error_message
|
135
145
|
end
|
136
146
|
|
137
147
|
##
|
@@ -0,0 +1,73 @@
|
|
1
|
+
module Airbrake
|
2
|
+
class Config
|
3
|
+
##
|
4
|
+
# Validates values of {Airbrake::Config} options.
|
5
|
+
#
|
6
|
+
# @api private
|
7
|
+
# @since v1.5.0
|
8
|
+
class Validator
|
9
|
+
##
|
10
|
+
# @return [String]
|
11
|
+
REQUIRED_KEY_MSG = ':project_key is required'.freeze
|
12
|
+
|
13
|
+
##
|
14
|
+
# @return [String]
|
15
|
+
REQUIRED_ID_MSG = ':project_id is required'.freeze
|
16
|
+
|
17
|
+
##
|
18
|
+
# @return [String]
|
19
|
+
WRONG_ENV_TYPE_MSG = "the 'environment' option must be configured " \
|
20
|
+
"with a Symbol (or String), but '%s' was provided: " \
|
21
|
+
"%s".freeze
|
22
|
+
|
23
|
+
##
|
24
|
+
# @return [Array<Class>] the list of allowed types to configure the
|
25
|
+
# environment option
|
26
|
+
VALID_ENV_TYPES = [NilClass, String, Symbol].freeze
|
27
|
+
|
28
|
+
##
|
29
|
+
# @return [String] error message, if validator was able to find any errors
|
30
|
+
# in the config
|
31
|
+
attr_reader :error_message
|
32
|
+
|
33
|
+
##
|
34
|
+
# Validates given config and stores error message, if any errors were
|
35
|
+
# found.
|
36
|
+
#
|
37
|
+
# @param config [Airbrake::Config] the config to validate
|
38
|
+
def initialize(config)
|
39
|
+
@config = config
|
40
|
+
@error_message = nil
|
41
|
+
end
|
42
|
+
|
43
|
+
##
|
44
|
+
# @return [Boolean]
|
45
|
+
def valid_project_id?
|
46
|
+
valid = @config.project_id.to_i > 0
|
47
|
+
@error_message = REQUIRED_ID_MSG unless valid
|
48
|
+
valid
|
49
|
+
end
|
50
|
+
|
51
|
+
##
|
52
|
+
# @return [Boolean]
|
53
|
+
def valid_project_key?
|
54
|
+
valid = @config.project_key.is_a?(String) && !@config.project_key.empty?
|
55
|
+
@error_message = REQUIRED_KEY_MSG unless valid
|
56
|
+
valid
|
57
|
+
end
|
58
|
+
|
59
|
+
##
|
60
|
+
# @return [Boolean]
|
61
|
+
def valid_environment?
|
62
|
+
environment = @config.environment
|
63
|
+
valid = VALID_ENV_TYPES.any? { |type| environment.is_a?(type) }
|
64
|
+
|
65
|
+
unless valid
|
66
|
+
@error_message = format(WRONG_ENV_TYPE_MSG, environment.class, environment)
|
67
|
+
end
|
68
|
+
|
69
|
+
valid
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -13,7 +13,10 @@ module Airbrake
|
|
13
13
|
notice[:errors].each do |error|
|
14
14
|
Gem.path.each do |gem_path|
|
15
15
|
error[:backtrace].each do |frame|
|
16
|
-
|
16
|
+
# If the frame is unparseable, then 'file' is nil, thus nothing to
|
17
|
+
# filter (all frame's data is in 'function' instead).
|
18
|
+
next unless (file = frame[:file])
|
19
|
+
file.sub!(/\A#{gem_path}/, '[GEM_ROOT]'.freeze)
|
17
20
|
end
|
18
21
|
end
|
19
22
|
end
|
@@ -67,7 +70,8 @@ module Airbrake
|
|
67
70
|
proc do |notice|
|
68
71
|
notice[:errors].each do |error|
|
69
72
|
error[:backtrace].each do |frame|
|
70
|
-
frame[:file]
|
73
|
+
next unless (file = frame[:file])
|
74
|
+
file.sub!(/\A#{root_directory}/, '[PROJECT_ROOT]'.freeze)
|
71
75
|
end
|
72
76
|
end
|
73
77
|
end
|
@@ -32,8 +32,12 @@ module Airbrake
|
|
32
32
|
def call(notice)
|
33
33
|
FILTERABLE_KEYS.each { |key| filter_hash(notice[key]) }
|
34
34
|
|
35
|
-
if notice[:context][:user]
|
36
|
-
|
35
|
+
if notice[:context][:user]
|
36
|
+
if should_filter?(:user)
|
37
|
+
notice[:context][:user] = FILTERED
|
38
|
+
else
|
39
|
+
filter_hash(notice[:context][:user])
|
40
|
+
end
|
37
41
|
end
|
38
42
|
|
39
43
|
return unless notice[:context][:url]
|
data/lib/airbrake-ruby/notice.rb
CHANGED
@@ -2,7 +2,9 @@ module Airbrake
|
|
2
2
|
##
|
3
3
|
# Represents a chunk of information that is meant to be either sent to
|
4
4
|
# Airbrake or ignored completely.
|
5
|
+
# rubocop:disable Metrics/ClassLength
|
5
6
|
class Notice
|
7
|
+
##
|
6
8
|
# @return [Hash{Symbol=>String}] the information about the notifier library
|
7
9
|
NOTIFIER = {
|
8
10
|
name: 'airbrake-ruby'.freeze,
|
@@ -66,6 +68,7 @@ module Airbrake
|
|
66
68
|
session: {},
|
67
69
|
params: params
|
68
70
|
}
|
71
|
+
extract_custom_attributes(exception)
|
69
72
|
|
70
73
|
@truncator = PayloadTruncator.new(PAYLOAD_MAX_SIZE, @config.logger)
|
71
74
|
end
|
@@ -199,5 +202,30 @@ module Airbrake
|
|
199
202
|
|
200
203
|
new_max_size
|
201
204
|
end
|
205
|
+
|
206
|
+
def extract_custom_attributes(exception)
|
207
|
+
return unless exception.respond_to?(:to_airbrake)
|
208
|
+
attributes = nil
|
209
|
+
|
210
|
+
begin
|
211
|
+
attributes = exception.to_airbrake
|
212
|
+
rescue => ex
|
213
|
+
@config.logger.error(
|
214
|
+
"#{LOG_LABEL} #{exception.class}#to_airbrake failed: #{ex.class}: #{ex}"
|
215
|
+
)
|
216
|
+
end
|
217
|
+
|
218
|
+
return unless attributes
|
219
|
+
|
220
|
+
begin
|
221
|
+
@modifiable_payload.merge!(attributes)
|
222
|
+
rescue TypeError
|
223
|
+
@config.logger.error(
|
224
|
+
"#{LOG_LABEL} #{exception.class}#to_airbrake failed:" \
|
225
|
+
" #{attributes} must be a Hash"
|
226
|
+
)
|
227
|
+
end
|
228
|
+
end
|
202
229
|
end
|
230
|
+
# rubocop:enable Metrics/ClassLength
|
203
231
|
end
|
@@ -31,7 +31,7 @@ module Airbrake
|
|
31
31
|
@config = (user_config.is_a?(Config) ? user_config : Config.new(user_config))
|
32
32
|
|
33
33
|
unless @config.valid?
|
34
|
-
raise Airbrake::Error,
|
34
|
+
raise Airbrake::Error, @config.validation_error_message
|
35
35
|
end
|
36
36
|
|
37
37
|
@filter_chain = FilterChain.new(@config)
|
data/spec/backtrace_spec.rb
CHANGED
@@ -76,6 +76,32 @@ RSpec.describe Airbrake::Backtrace do
|
|
76
76
|
end
|
77
77
|
end
|
78
78
|
|
79
|
+
context "JRuby classloader exceptions" do
|
80
|
+
let(:backtrace) do
|
81
|
+
# rubocop:disable Metrics/LineLength
|
82
|
+
['uri_3a_classloader_3a_.META_minus_INF.jruby_dot_home.lib.ruby.stdlib.net.protocol.rbuf_fill(uri:classloader:/META-INF/jruby.home/lib/ruby/stdlib/net/protocol.rb:158)',
|
83
|
+
'bin.processors.image_uploader.block in make_streams(bin/processors/image_uploader.rb:21)']
|
84
|
+
# rubocop:enable Metrics/LineLength
|
85
|
+
end
|
86
|
+
|
87
|
+
let(:parsed_backtrace) do
|
88
|
+
# rubocop:disable Metrics/LineLength
|
89
|
+
[{ file: 'uri:classloader:/META-INF/jruby.home/lib/ruby/stdlib/net/protocol.rb', line: 158, function: 'uri_3a_classloader_3a_.META_minus_INF.jruby_dot_home.lib.ruby.stdlib.net.protocol.rbuf_fill' },
|
90
|
+
{ file: 'bin/processors/image_uploader.rb', line: 21, function: 'bin.processors.image_uploader.block in make_streams' }]
|
91
|
+
# rubocop:enable Metrics/LineLength
|
92
|
+
end
|
93
|
+
|
94
|
+
let(:ex) { JavaAirbrakeTestError.new.tap { |e| e.set_backtrace(backtrace) } }
|
95
|
+
|
96
|
+
it "returns a properly formatted array of hashes" do
|
97
|
+
allow(described_class).to receive(:java_exception?).and_return(true)
|
98
|
+
|
99
|
+
expect(
|
100
|
+
described_class.parse(ex, Logger.new('/dev/null'))
|
101
|
+
).to eq(parsed_backtrace)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
79
105
|
context "generic backtrace" do
|
80
106
|
context "when function is absent" do
|
81
107
|
# rubocop:disable Metrics/LineLength
|
@@ -0,0 +1,189 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe Airbrake::Config::Validator do
|
4
|
+
subject { described_class.new(config) }
|
5
|
+
|
6
|
+
describe "#valid_project_id?" do
|
7
|
+
context "when project id is zero" do
|
8
|
+
let(:config) { Airbrake::Config.new(project_id: 0) }
|
9
|
+
|
10
|
+
it "returns false" do
|
11
|
+
expect(subject.valid_project_id?).to be false
|
12
|
+
end
|
13
|
+
|
14
|
+
it "sets correct error message" do
|
15
|
+
expect { subject.valid_project_id? }.
|
16
|
+
to change { subject.error_message }.
|
17
|
+
to(/:project_id is required/)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
context "when project_id is a String" do
|
22
|
+
let(:config) { Airbrake::Config.new(project_id: '000') }
|
23
|
+
|
24
|
+
context "and when it's zero" do
|
25
|
+
it "returns false" do
|
26
|
+
expect(subject.valid_project_id?).to be false
|
27
|
+
end
|
28
|
+
|
29
|
+
it "sets correct error message" do
|
30
|
+
expect { subject.valid_project_id? }.
|
31
|
+
to change { subject.error_message }.
|
32
|
+
to(/:project_id is required/)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
context "and when it consists of letters" do
|
37
|
+
let(:config) { Airbrake::Config.new(project_id: 'bingo') }
|
38
|
+
|
39
|
+
it "returns false" do
|
40
|
+
expect(subject.valid_project_id?).to be false
|
41
|
+
end
|
42
|
+
|
43
|
+
it "sets correct error message" do
|
44
|
+
expect { subject.valid_project_id? }.
|
45
|
+
to change { subject.error_message }.
|
46
|
+
to(/:project_id is required/)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
context "and when it's numerical" do
|
51
|
+
let(:config) { Airbrake::Config.new(project_id: '123') }
|
52
|
+
|
53
|
+
it "returns true" do
|
54
|
+
expect(subject.valid_project_id?).to be true
|
55
|
+
end
|
56
|
+
|
57
|
+
it "doesn't set the error message" do
|
58
|
+
expect { subject.valid_project_id? }.not_to change { subject.error_message }
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
context "when project id is non-zero" do
|
64
|
+
let(:config) { Airbrake::Config.new(project_id: 123) }
|
65
|
+
|
66
|
+
it "returns true" do
|
67
|
+
expect(subject.valid_project_id?).to be true
|
68
|
+
end
|
69
|
+
|
70
|
+
it "doesn't set the error message" do
|
71
|
+
expect { subject.valid_project_id? }.not_to change { subject.error_message }
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
describe "#valid_project_key?" do
|
77
|
+
context "when it's a String" do
|
78
|
+
context "and when it's empty" do
|
79
|
+
let(:config) { Airbrake::Config.new(project_key: '') }
|
80
|
+
|
81
|
+
it "returns false" do
|
82
|
+
expect(subject.valid_project_key?).to be false
|
83
|
+
end
|
84
|
+
|
85
|
+
it "sets correct error message" do
|
86
|
+
expect { subject.valid_project_key? }.
|
87
|
+
to change { subject.error_message }.
|
88
|
+
to(/:project_key is required/)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
context "and when it's non-empty" do
|
93
|
+
let(:config) { Airbrake::Config.new(project_key: '123abc') }
|
94
|
+
|
95
|
+
it "returns true" do
|
96
|
+
expect(subject.valid_project_key?).to be true
|
97
|
+
end
|
98
|
+
|
99
|
+
it "doesn't set the error message" do
|
100
|
+
expect { subject.valid_project_key? }.not_to change { subject.error_message }
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
context "when it's not a String" do
|
106
|
+
let(:config) { Airbrake::Config.new(project_key: 123) }
|
107
|
+
|
108
|
+
it "returns false" do
|
109
|
+
expect(subject.valid_project_key?).to be false
|
110
|
+
end
|
111
|
+
|
112
|
+
it "sets correct error message" do
|
113
|
+
expect { subject.valid_project_key? }.
|
114
|
+
to change { subject.error_message }.
|
115
|
+
to(/:project_key is required/)
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
describe "#valid_environment?" do
|
121
|
+
context "when config.environment is not set" do
|
122
|
+
let(:config) { Airbrake::Config.new }
|
123
|
+
|
124
|
+
it "returns true" do
|
125
|
+
expect(subject.valid_environment?).to be true
|
126
|
+
end
|
127
|
+
|
128
|
+
it "doesn't set the error message" do
|
129
|
+
expect { subject.valid_environment? }.not_to change { subject.error_message }
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
context "when config.environment is set" do
|
134
|
+
context "and when it is not a Symbol or String" do
|
135
|
+
let(:config) { Airbrake::Config.new(environment: 123) }
|
136
|
+
|
137
|
+
it "returns false" do
|
138
|
+
expect(subject.valid_environment?).to be false
|
139
|
+
end
|
140
|
+
|
141
|
+
it "sets the error message" do
|
142
|
+
expect { subject.valid_environment? }.
|
143
|
+
to change { subject.error_message }.
|
144
|
+
to(/the 'environment' option must be configured with a Symbol/)
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
context "and when it is a Symbol" do
|
149
|
+
let(:config) { Airbrake::Config.new(environment: :bingo) }
|
150
|
+
|
151
|
+
it "returns true" do
|
152
|
+
expect(subject.valid_environment?).to be true
|
153
|
+
end
|
154
|
+
|
155
|
+
it "doesn't set the error message" do
|
156
|
+
expect { subject.valid_environment? }.not_to change { subject.error_message }
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
context "and when it is a String" do
|
161
|
+
let(:config) { Airbrake::Config.new(environment: 'bingo') }
|
162
|
+
|
163
|
+
it "returns true" do
|
164
|
+
expect(subject.valid_environment?).to be true
|
165
|
+
end
|
166
|
+
|
167
|
+
it "doesn't set the error message" do
|
168
|
+
expect { subject.valid_environment? }.not_to change { subject.error_message }
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
context "and when it is kind of a String" do
|
173
|
+
let(:string_inquirer) { Class.new(String) }
|
174
|
+
|
175
|
+
let(:config) do
|
176
|
+
Airbrake::Config.new(environment: string_inquirer.new('bingo'))
|
177
|
+
end
|
178
|
+
|
179
|
+
it "returns true" do
|
180
|
+
expect(subject.valid_environment?).to be true
|
181
|
+
end
|
182
|
+
|
183
|
+
it "doesn't set the error message" do
|
184
|
+
expect { subject.valid_environment? }.not_to change { subject.error_message }
|
185
|
+
end
|
186
|
+
end
|
187
|
+
end
|
188
|
+
end
|
189
|
+
end
|
data/spec/config_spec.rb
CHANGED
@@ -155,6 +155,22 @@ RSpec.describe Airbrake::Config do
|
|
155
155
|
expect(config).not_to be_valid
|
156
156
|
end
|
157
157
|
end
|
158
|
+
|
159
|
+
context "when the environment value is not a String" do
|
160
|
+
let(:out) { StringIO.new }
|
161
|
+
let(:config) { described_class.new(logger: Logger.new(out)) }
|
162
|
+
|
163
|
+
before do
|
164
|
+
config.project_id = 123
|
165
|
+
config.project_key = '321'
|
166
|
+
|
167
|
+
config.environment = ['bingo']
|
168
|
+
end
|
169
|
+
|
170
|
+
it "returns false" do
|
171
|
+
expect(config).not_to be_valid
|
172
|
+
end
|
173
|
+
end
|
158
174
|
end
|
159
175
|
|
160
176
|
describe "#ignored_environment?" do
|
data/spec/filter_chain_spec.rb
CHANGED
@@ -152,6 +152,42 @@ RSpec.describe Airbrake::FilterChain do
|
|
152
152
|
to(change { notice.ignored? }.from(false).to(true))
|
153
153
|
end
|
154
154
|
end
|
155
|
+
|
156
|
+
context "gem root filter" do
|
157
|
+
let(:ex) do
|
158
|
+
AirbrakeTestError.new.tap do |error|
|
159
|
+
error.set_backtrace(['(unparseable/frame.rb:23)'])
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
it "does not filter file if it is nil" do
|
164
|
+
config.logger = Logger.new('/dev/null')
|
165
|
+
notice = Airbrake::Notice.new(config, ex)
|
166
|
+
|
167
|
+
expect(notice[:errors].first[:file]).to be_nil
|
168
|
+
expect { @chain.refine(notice) }.
|
169
|
+
not_to change { notice[:errors].first[:file] }
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
context "root directory filter" do
|
174
|
+
let(:ex) do
|
175
|
+
AirbrakeTestError.new.tap do |error|
|
176
|
+
error.set_backtrace(['(unparseable/frame.rb:23)'])
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
it "does not filter file if it is nil" do
|
181
|
+
config.logger = Logger.new('/dev/null')
|
182
|
+
config.root_directory = '/bingo/bango'
|
183
|
+
notice = Airbrake::Notice.new(config, ex)
|
184
|
+
filter_chain = described_class.new(config)
|
185
|
+
|
186
|
+
expect(notice[:errors].first[:file]).to be_nil
|
187
|
+
expect { filter_chain.refine(notice) }.
|
188
|
+
not_to change { notice[:errors].first[:file] }
|
189
|
+
end
|
190
|
+
end
|
155
191
|
end
|
156
192
|
end
|
157
193
|
end
|
data/spec/notice_spec.rb
CHANGED
@@ -5,6 +5,75 @@ RSpec.describe Airbrake::Notice do
|
|
5
5
|
described_class.new(Airbrake::Config.new, AirbrakeTestError.new, bingo: '1')
|
6
6
|
end
|
7
7
|
|
8
|
+
describe "#new" do
|
9
|
+
let(:params) do
|
10
|
+
{ bingo: 'bango', bongo: 'bish' }
|
11
|
+
end
|
12
|
+
|
13
|
+
let(:ex) { airbrake_exception_class.new(params) }
|
14
|
+
|
15
|
+
context "given an exception class, which supports #to_airbrake" do
|
16
|
+
context "and when #to_airbrake returns a non-Hash object" do
|
17
|
+
let(:airbrake_exception_class) do
|
18
|
+
Class.new(AirbrakeTestError) do
|
19
|
+
def to_airbrake
|
20
|
+
Object.new
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
it "rescues the error, logs it and doesn't modify the payload" do
|
26
|
+
out = StringIO.new
|
27
|
+
config = Airbrake::Config.new(logger: Logger.new(out))
|
28
|
+
notice = nil
|
29
|
+
|
30
|
+
expect { notice = described_class.new(config, ex) }.not_to raise_error
|
31
|
+
expect(out.string).to match(/#to_airbrake failed:.+Object.+must be a Hash/)
|
32
|
+
expect(notice[:params]).to be_empty
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
context "and when #to_airbrake errors out" do
|
37
|
+
let(:airbrake_exception_class) do
|
38
|
+
Class.new(AirbrakeTestError) do
|
39
|
+
def to_airbrake
|
40
|
+
1 / 0
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
it "rescues the error, logs it and doesn't modify the payload" do
|
46
|
+
out = StringIO.new
|
47
|
+
config = Airbrake::Config.new(logger: Logger.new(out))
|
48
|
+
notice = nil
|
49
|
+
|
50
|
+
expect { notice = described_class.new(config, ex) }.not_to raise_error
|
51
|
+
expect(out.string).to match(/#to_airbrake failed: ZeroDivisionError/)
|
52
|
+
expect(notice[:params]).to be_empty
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
context "and when #to_airbrake succeeds" do
|
57
|
+
let(:airbrake_exception_class) do
|
58
|
+
Class.new(AirbrakeTestError) do
|
59
|
+
def initialize(params)
|
60
|
+
@params = params
|
61
|
+
end
|
62
|
+
|
63
|
+
def to_airbrake
|
64
|
+
{ params: @params }
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
it "merges the parameters with the notice" do
|
70
|
+
notice = described_class.new(Airbrake::Config.new, ex)
|
71
|
+
expect(notice[:params]).to eq(params)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
8
77
|
describe "#to_json" do
|
9
78
|
context "app_version" do
|
10
79
|
context "when missing" do
|
data/spec/notifier_spec.rb
CHANGED
@@ -30,21 +30,18 @@ RSpec.describe Airbrake::Notifier do
|
|
30
30
|
describe "#new" do
|
31
31
|
context "raises error if" do
|
32
32
|
example ":project_id is not provided" do
|
33
|
-
expect { described_class.new(
|
34
|
-
to raise_error(Airbrake::Error,
|
35
|
-
'both :project_id and :project_key are required')
|
33
|
+
expect { described_class.new(project_key: project_key) }.
|
34
|
+
to raise_error(Airbrake::Error, ':project_id is required')
|
36
35
|
end
|
37
36
|
|
38
37
|
example ":project_key is not provided" do
|
39
|
-
expect { described_class.new(
|
40
|
-
to raise_error(Airbrake::Error,
|
41
|
-
'both :project_id and :project_key are required')
|
38
|
+
expect { described_class.new(project_id: project_id) }.
|
39
|
+
to raise_error(Airbrake::Error, ':project_key is required')
|
42
40
|
end
|
43
41
|
|
44
42
|
example "neither :project_id nor :project_key are provided" do
|
45
43
|
expect { described_class.new({}) }.
|
46
|
-
to raise_error(Airbrake::Error,
|
47
|
-
'both :project_id and :project_key are required')
|
44
|
+
to raise_error(Airbrake::Error, ':project_id is required')
|
48
45
|
end
|
49
46
|
end
|
50
47
|
|
@@ -571,6 +568,17 @@ RSpec.describe Airbrake::Notifier do
|
|
571
568
|
|
572
569
|
expect_a_request_with_body(/"user":"\[Filtered\]"/)
|
573
570
|
end
|
571
|
+
|
572
|
+
it "filters out individual user fields" do
|
573
|
+
@airbrake.blacklist_keys('name')
|
574
|
+
|
575
|
+
notice = @airbrake.build_notice(ex)
|
576
|
+
notice[:context][:user] = { id: 1337, name: 'Bingo Bango' }
|
577
|
+
|
578
|
+
@airbrake.notify_sync(notice)
|
579
|
+
|
580
|
+
expect_a_request_with_body(/"user":{"id":1337,"name":"\[Filtered\]"}/)
|
581
|
+
end
|
574
582
|
end
|
575
583
|
|
576
584
|
describe "#whitelist_keys" do
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: airbrake-ruby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Airbrake Technologies, Inc.
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-09-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rspec
|
@@ -99,6 +99,7 @@ files:
|
|
99
99
|
- lib/airbrake-ruby/async_sender.rb
|
100
100
|
- lib/airbrake-ruby/backtrace.rb
|
101
101
|
- lib/airbrake-ruby/config.rb
|
102
|
+
- lib/airbrake-ruby/config/validator.rb
|
102
103
|
- lib/airbrake-ruby/filter_chain.rb
|
103
104
|
- lib/airbrake-ruby/filters.rb
|
104
105
|
- lib/airbrake-ruby/filters/keys_blacklist.rb
|
@@ -114,6 +115,7 @@ files:
|
|
114
115
|
- spec/airbrake_spec.rb
|
115
116
|
- spec/async_sender_spec.rb
|
116
117
|
- spec/backtrace_spec.rb
|
118
|
+
- spec/config/validator_spec.rb
|
117
119
|
- spec/config_spec.rb
|
118
120
|
- spec/filter_chain_spec.rb
|
119
121
|
- spec/nested_exception_spec.rb
|
@@ -151,6 +153,7 @@ test_files:
|
|
151
153
|
- spec/airbrake_spec.rb
|
152
154
|
- spec/async_sender_spec.rb
|
153
155
|
- spec/backtrace_spec.rb
|
156
|
+
- spec/config/validator_spec.rb
|
154
157
|
- spec/config_spec.rb
|
155
158
|
- spec/filter_chain_spec.rb
|
156
159
|
- spec/nested_exception_spec.rb
|