airbrake-ruby 1.4.6 → 1.5.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 +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
|