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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4e55d1ef72a4b324c33893e56abd9e92c661461c
4
- data.tar.gz: 14b98e0a8ba23394efd7c967add4ce0bdc93042c
3
+ metadata.gz: 2498350f956db613816b9cf8ae1579a01b0ca940
4
+ data.tar.gz: 3bafaf42dc712d226ac97b3ad5690f923ff49cc6
5
5
  SHA512:
6
- metadata.gz: 33b3db9de069c13caf56f7b63b423e4ef83730b6f40398e251e9bd075d043d5b1aada097884748394d315af95e76274841e616a610dfe3f99d8cb93eed22f83f
7
- data.tar.gz: 5f99f46b2ad687d9f9b3a11505c8189620a2f18ac63f4bb7fe5436c7b9aa88b3880f7adb0ca8f88edee299d92619e410c31f2915bff5861d3148551253c339eb
6
+ metadata.gz: 097a7a2681e0d28b020ea43a918b96ed0c89167a96d7b8146f27bac98682d95b61431ffe6eb1d78d278068b6321e4c28f196dec021c8a7fb7ed31c7e6465cc3d
7
+ data.tar.gz: 3cfdaaf798e0b85835126535434bb10bff78422b1b8890e924cf881b2b3843f0230eea43eaf6efdf0f9e3296941c2e85c217d71d6ed69b8caae3ae94be4baec7
data/lib/airbrake-ruby.rb CHANGED
@@ -7,6 +7,7 @@ require 'socket'
7
7
 
8
8
  require 'airbrake-ruby/version'
9
9
  require 'airbrake-ruby/config'
10
+ require 'airbrake-ruby/config/validator'
10
11
  require 'airbrake-ruby/sync_sender'
11
12
  require 'airbrake-ruby/async_sender'
12
13
  require 'airbrake-ruby/response'
@@ -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 = /\A
30
- (?<function>.+) # Matches 'org.jruby.ast.NewlineNode.interpret
29
+ JAVA = %r{\A
30
+ (?<function>.+) # Matches 'org.jruby.ast.NewlineNode.interpret'
31
31
  \(
32
- (?<file>[^:]+) # Matches 'NewlineNode.java'
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/x
40
+ \z}x
37
41
 
38
42
  ##
39
43
  # @return [Regexp] the pattern that tries to assume what a generic stack
@@ -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
- return false if project_id.to_i.zero?
134
- project_key.is_a?(String) && !project_key.empty?
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
- frame[:file].sub!(/\A#{gem_path}/, '[GEM_ROOT]'.freeze)
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].sub!(/\A#{root_directory}/, '[PROJECT_ROOT]'.freeze)
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] && should_filter?(:user)
36
- notice[:context][:user] = FILTERED
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]
@@ -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, 'both :project_id and :project_key are required'
34
+ raise Airbrake::Error, @config.validation_error_message
35
35
  end
36
36
 
37
37
  @filter_chain = FilterChain.new(@config)
@@ -4,5 +4,5 @@
4
4
  module Airbrake
5
5
  ##
6
6
  # @return [String] the library version
7
- AIRBRAKE_RUBY_VERSION = '1.4.6'.freeze
7
+ AIRBRAKE_RUBY_VERSION = '1.5.0'.freeze
8
8
  end
@@ -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
@@ -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
@@ -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(project_id: project_id) }.
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(project_key: project_key) }.
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.6
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-08-18 00:00:00.000000000 Z
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