airbrake-ruby 2.2.3 → 2.2.4
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 -2
- data/lib/airbrake-ruby/filter_chain.rb +1 -25
- data/lib/airbrake-ruby/filters/keys_filter.rb +5 -0
- data/lib/airbrake-ruby/filters/thread_filter.rb +25 -12
- data/lib/airbrake-ruby/notice.rb +11 -21
- data/lib/airbrake-ruby/notifier.rb +24 -4
- data/lib/airbrake-ruby/{payload_truncator.rb → truncator.rb} +22 -39
- data/lib/airbrake-ruby/version.rb +1 -1
- data/spec/filter_chain_spec.rb +22 -198
- data/spec/filters/gem_root_filter_spec.rb +46 -0
- data/spec/filters/keys_blacklist_spec.rb +181 -6
- data/spec/filters/keys_whitelist_spec.rb +213 -0
- data/spec/filters/root_directory_filter_spec.rb +44 -0
- data/spec/filters/system_exit_filter_spec.rb +16 -0
- data/spec/filters/thread_filter_spec.rb +197 -51
- data/spec/notice_spec.rb +1 -1
- data/spec/sync_sender_spec.rb +1 -1
- data/spec/{payload_truncator_spec.rb → truncator_spec.rb} +15 -35
- metadata +13 -10
- data/lib/airbrake-ruby/filters.rb +0 -10
- data/spec/notifier_spec/blacklist_keys_spec.rb +0 -192
- data/spec/notifier_spec/whitelist_keys_spec.rb +0 -248
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe Airbrake::Filters::RootDirectoryFilter do
|
4
|
+
subject { described_class.new(root_directory) }
|
5
|
+
|
6
|
+
let(:root_directory) { '/var/www/project' }
|
7
|
+
|
8
|
+
let(:notice) do
|
9
|
+
Airbrake::Notice.new(Airbrake::Config.new, AirbrakeTestError.new)
|
10
|
+
end
|
11
|
+
|
12
|
+
it "replaces root directory in the backtrace with a label" do
|
13
|
+
# rubocop:disable Metrics/LineLength
|
14
|
+
notice[:errors].first[:backtrace] = [
|
15
|
+
{ file: "/home/kyrylo/code/airbrake/ruby/spec/spec_helper.rb" },
|
16
|
+
{ file: "#{root_directory}/gems/rspec-core-3.3.2/lib/rspec/core/configuration.rb " },
|
17
|
+
{ file: "/opt/rubies/ruby-2.2.2/lib/ruby/2.2.0/rubygems/core_ext/kernel_require.rb" },
|
18
|
+
{ file: "#{root_directory}/gems/rspec-core-3.3.2/exe/rspec" }
|
19
|
+
]
|
20
|
+
# rubocop:enable Metrics/LineLength
|
21
|
+
|
22
|
+
subject.call(notice)
|
23
|
+
|
24
|
+
# rubocop:disable Metrics/LineLength
|
25
|
+
expect(notice[:errors].first[:backtrace]).to(
|
26
|
+
eq(
|
27
|
+
[
|
28
|
+
{ file: "/home/kyrylo/code/airbrake/ruby/spec/spec_helper.rb" },
|
29
|
+
{ file: "[PROJECT_ROOT]/gems/rspec-core-3.3.2/lib/rspec/core/configuration.rb " },
|
30
|
+
{ file: "/opt/rubies/ruby-2.2.2/lib/ruby/2.2.0/rubygems/core_ext/kernel_require.rb" },
|
31
|
+
{ file: "[PROJECT_ROOT]/gems/rspec-core-3.3.2/exe/rspec" }
|
32
|
+
]
|
33
|
+
)
|
34
|
+
)
|
35
|
+
# rubocop:enable Metrics/LineLength
|
36
|
+
end
|
37
|
+
|
38
|
+
it "does not filter file when it is nil" do
|
39
|
+
expect(notice[:errors].first[:file]).to be_nil
|
40
|
+
expect { subject.call(notice) }.not_to(
|
41
|
+
change { notice[:errors].first[:file] }
|
42
|
+
)
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe Airbrake::Filters::SystemExitFilter do
|
4
|
+
it "marks SystemExit exceptions as ignored" do
|
5
|
+
notice = Airbrake::Notice.new(Airbrake::Config.new, SystemExit.new)
|
6
|
+
expect { subject.call(notice) }.to(
|
7
|
+
change { notice.ignored? }.from(false).to(true)
|
8
|
+
)
|
9
|
+
end
|
10
|
+
|
11
|
+
it "doesn't mark non SystemExit exceptions as ignored" do
|
12
|
+
notice = Airbrake::Notice.new(Airbrake::Config.new, AirbrakeTestError.new)
|
13
|
+
expect(notice).not_to be_ignored
|
14
|
+
expect { subject.call(notice) }.not_to(change { notice.ignored? })
|
15
|
+
end
|
16
|
+
end
|
@@ -16,38 +16,214 @@ RSpec.describe Airbrake::Filters::ThreadFilter do
|
|
16
16
|
end.join
|
17
17
|
end
|
18
18
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
19
|
+
describe "thread variables" do
|
20
|
+
shared_examples "expected thread variable" do |var|
|
21
|
+
it "attaches the thread variable" do
|
22
|
+
new_thread do |th|
|
23
|
+
th.thread_variable_set(:bingo, var)
|
24
|
+
subject.call(notice)
|
25
|
+
end
|
26
|
+
|
27
|
+
expect(notice[:params][:thread][:thread_variables][:bingo]).to eq(var)
|
24
28
|
end
|
29
|
+
end
|
25
30
|
|
26
|
-
|
27
|
-
|
31
|
+
context "given nil" do
|
32
|
+
include_examples "expected thread variable", nil
|
28
33
|
end
|
29
|
-
end
|
30
34
|
|
31
|
-
|
32
|
-
|
33
|
-
|
35
|
+
context "given true" do
|
36
|
+
include_examples "expected thread variable", true
|
37
|
+
end
|
34
38
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
+
context "given false" do
|
40
|
+
include_examples "expected thread variable", false
|
41
|
+
end
|
42
|
+
|
43
|
+
context "given a String" do
|
44
|
+
include_examples "expected thread variable", 'bango'
|
45
|
+
end
|
46
|
+
|
47
|
+
context "given a Symbol" do
|
48
|
+
include_examples "expected thread variable", :bango
|
49
|
+
end
|
50
|
+
|
51
|
+
context "given a Regexp" do
|
52
|
+
include_examples "expected thread variable", /bango/
|
53
|
+
end
|
54
|
+
|
55
|
+
context "given an Integer" do
|
56
|
+
include_examples "expected thread variable", 1
|
57
|
+
end
|
58
|
+
|
59
|
+
context "given a Float" do
|
60
|
+
include_examples "expected thread variable", 1.01
|
39
61
|
end
|
40
62
|
|
41
|
-
|
63
|
+
context "given an Object" do
|
64
|
+
it "converts it to a String and attaches" do
|
65
|
+
new_thread do |th|
|
66
|
+
th.thread_variable_set(:bingo, Object.new)
|
67
|
+
subject.call(notice)
|
68
|
+
end
|
69
|
+
|
70
|
+
vars = notice[:params][:thread][:thread_variables]
|
71
|
+
expect(vars[:bingo]).to match(/\A#<Object:.+>\z/)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
context "given an Array of nested Hashes with complex objects" do
|
76
|
+
let(:var) do
|
77
|
+
[
|
78
|
+
{
|
79
|
+
bango: {
|
80
|
+
bongo: [
|
81
|
+
{
|
82
|
+
bish: {
|
83
|
+
bash: 'foo',
|
84
|
+
bosh: Object.new
|
85
|
+
}
|
86
|
+
}
|
87
|
+
]
|
88
|
+
}
|
89
|
+
},
|
90
|
+
123
|
91
|
+
]
|
92
|
+
end
|
93
|
+
|
94
|
+
it "converts objects to a safe objects" do
|
95
|
+
new_thread do |th|
|
96
|
+
th.thread_variable_set(:bingo, var)
|
97
|
+
subject.call(notice)
|
98
|
+
end
|
99
|
+
|
100
|
+
vars = notice[:params][:thread][:thread_variables]
|
101
|
+
expect(vars[:bingo]).to(
|
102
|
+
match(
|
103
|
+
[
|
104
|
+
{
|
105
|
+
bango: {
|
106
|
+
bongo: [
|
107
|
+
{
|
108
|
+
bish: {
|
109
|
+
bash: 'foo',
|
110
|
+
bosh: /\A#<Object:.+>\z/
|
111
|
+
}
|
112
|
+
}
|
113
|
+
]
|
114
|
+
}
|
115
|
+
},
|
116
|
+
123
|
117
|
+
]
|
118
|
+
)
|
119
|
+
)
|
120
|
+
end
|
121
|
+
end
|
42
122
|
end
|
43
123
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
124
|
+
describe "fiber variables" do
|
125
|
+
shared_examples "expected fiber variable" do |var|
|
126
|
+
it "attaches the fiber variable" do
|
127
|
+
new_thread do |th|
|
128
|
+
th[:bingo] = var
|
129
|
+
subject.call(notice)
|
130
|
+
end
|
131
|
+
|
132
|
+
expect(notice[:params][:thread][:fiber_variables][:bingo]).to eq(var)
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
context "given nil" do
|
137
|
+
include_examples "expected fiber variable", nil
|
138
|
+
end
|
139
|
+
|
140
|
+
context "given true" do
|
141
|
+
include_examples "expected fiber variable", true
|
48
142
|
end
|
49
143
|
|
50
|
-
|
144
|
+
context "given false" do
|
145
|
+
include_examples "expected fiber variable", false
|
146
|
+
end
|
147
|
+
|
148
|
+
context "given a String" do
|
149
|
+
include_examples "expected fiber variable", 'bango'
|
150
|
+
end
|
151
|
+
|
152
|
+
context "given a Symbol" do
|
153
|
+
include_examples "expected fiber variable", :bango
|
154
|
+
end
|
155
|
+
|
156
|
+
context "given a Regexp" do
|
157
|
+
include_examples "expected fiber variable", /bango/
|
158
|
+
end
|
159
|
+
|
160
|
+
context "given an Integer" do
|
161
|
+
include_examples "expected fiber variable", 1
|
162
|
+
end
|
163
|
+
|
164
|
+
context "given a Float" do
|
165
|
+
include_examples "expected fiber variable", 1.01
|
166
|
+
end
|
167
|
+
|
168
|
+
context "given an Object" do
|
169
|
+
it "converts it to a String and attaches" do
|
170
|
+
new_thread do |th|
|
171
|
+
th[:bingo] = Object.new
|
172
|
+
subject.call(notice)
|
173
|
+
end
|
174
|
+
|
175
|
+
vars = notice[:params][:thread][:fiber_variables]
|
176
|
+
expect(vars[:bingo]).to match(/\A#<Object:.+>\z/)
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
context "given an Array of nested Hashes with complex objects" do
|
181
|
+
let(:var) do
|
182
|
+
[
|
183
|
+
{
|
184
|
+
bango: {
|
185
|
+
bongo: [
|
186
|
+
{
|
187
|
+
bish: {
|
188
|
+
bash: 'foo',
|
189
|
+
bosh: Object.new
|
190
|
+
}
|
191
|
+
}
|
192
|
+
]
|
193
|
+
}
|
194
|
+
},
|
195
|
+
123
|
196
|
+
]
|
197
|
+
end
|
198
|
+
|
199
|
+
it "converts objects to a safe objects" do
|
200
|
+
new_thread do |th|
|
201
|
+
th[:bingo] = var
|
202
|
+
subject.call(notice)
|
203
|
+
end
|
204
|
+
|
205
|
+
vars = notice[:params][:thread][:fiber_variables]
|
206
|
+
expect(vars[:bingo]).to(
|
207
|
+
match(
|
208
|
+
[
|
209
|
+
{
|
210
|
+
bango: {
|
211
|
+
bongo: [
|
212
|
+
{
|
213
|
+
bish: {
|
214
|
+
bash: 'foo',
|
215
|
+
bosh: /\A#<Object:.+>\z/
|
216
|
+
}
|
217
|
+
}
|
218
|
+
]
|
219
|
+
}
|
220
|
+
},
|
221
|
+
123
|
222
|
+
]
|
223
|
+
)
|
224
|
+
)
|
225
|
+
end
|
226
|
+
end
|
51
227
|
end
|
52
228
|
|
53
229
|
it "appends name", skip: !Thread.current.respond_to?(:name) do
|
@@ -78,34 +254,4 @@ RSpec.describe Airbrake::Filters::ThreadFilter do
|
|
78
254
|
subject.call(notice)
|
79
255
|
expect(notice[:params][:thread][:safe_level]).to eq(0)
|
80
256
|
end
|
81
|
-
|
82
|
-
context "when an IO-like object is stored" do
|
83
|
-
let(:io_obj) do
|
84
|
-
Class.new(IO) do
|
85
|
-
def initialize; end
|
86
|
-
end.new
|
87
|
-
end
|
88
|
-
|
89
|
-
before do
|
90
|
-
expect(io_obj).to be_is_a(IO)
|
91
|
-
end
|
92
|
-
|
93
|
-
it "doesn't append the IO object to thread variables" do
|
94
|
-
new_thread do |th|
|
95
|
-
th.thread_variable_set(:io, io_obj)
|
96
|
-
subject.call(notice)
|
97
|
-
end
|
98
|
-
|
99
|
-
expect(notice[:params][:thread][:thread_variables]).to be_nil
|
100
|
-
end
|
101
|
-
|
102
|
-
it "doesn't append the IO object to thread variables" do
|
103
|
-
new_thread do |th|
|
104
|
-
th[:io] = io_obj
|
105
|
-
subject.call(notice)
|
106
|
-
end
|
107
|
-
|
108
|
-
expect(notice[:params][:thread][:fiber_variables][:io]).to be_nil
|
109
|
-
end
|
110
|
-
end
|
111
257
|
end
|
data/spec/notice_spec.rb
CHANGED
@@ -136,7 +136,7 @@ RSpec.describe Airbrake::Notice do
|
|
136
136
|
|
137
137
|
context "when truncation failed" do
|
138
138
|
it "returns nil" do
|
139
|
-
expect_any_instance_of(Airbrake::
|
139
|
+
expect_any_instance_of(Airbrake::Truncator).
|
140
140
|
to receive(:reduce_max_size).and_return(0)
|
141
141
|
|
142
142
|
encoded = Base64.encode64("\xD3\xE6\xBC\x9D\xBA").encode!('ASCII-8BIT')
|
data/spec/sync_sender_spec.rb
CHANGED
@@ -29,7 +29,7 @@ RSpec.describe Airbrake::SyncSender do
|
|
29
29
|
|
30
30
|
context "when request body is nil" do
|
31
31
|
it "doesn't send a notice" do
|
32
|
-
expect_any_instance_of(Airbrake::
|
32
|
+
expect_any_instance_of(Airbrake::Truncator).
|
33
33
|
to receive(:reduce_max_size).and_return(0)
|
34
34
|
|
35
35
|
encoded = Base64.encode64("\xD3\xE6\xBC\x9D\xBA").encode!('ASCII-8BIT')
|
@@ -2,32 +2,28 @@
|
|
2
2
|
|
3
3
|
require 'spec_helper'
|
4
4
|
|
5
|
-
RSpec.describe Airbrake::
|
5
|
+
RSpec.describe Airbrake::Truncator do
|
6
6
|
let(:max_size) { 1000 }
|
7
7
|
let(:truncated_len) { '[Truncated]'.length }
|
8
8
|
let(:max_len) { max_size + truncated_len }
|
9
9
|
|
10
10
|
before do
|
11
|
-
@truncator = described_class.new(max_size
|
11
|
+
@truncator = described_class.new(max_size)
|
12
12
|
end
|
13
13
|
|
14
|
-
describe "#
|
15
|
-
let(:error) do
|
16
|
-
{ type: 'AirbrakeTestError', message: 'App crashed!', backtrace: [] }
|
17
|
-
end
|
18
|
-
|
19
|
-
before do
|
20
|
-
@stdout = StringIO.new
|
21
|
-
end
|
22
|
-
|
14
|
+
describe "#truncate_object" do
|
23
15
|
describe "error backtrace" do
|
16
|
+
let(:error) do
|
17
|
+
{ type: 'AirbrakeTestError', message: 'App crashed!', backtrace: [] }
|
18
|
+
end
|
19
|
+
|
24
20
|
before do
|
25
21
|
backtrace = Array.new(size) do
|
26
22
|
{ file: 'foo.rb', line: 23, function: '<main>' }
|
27
23
|
end
|
28
24
|
|
29
25
|
@error = error.merge(backtrace: backtrace)
|
30
|
-
described_class.new(max_size
|
26
|
+
described_class.new(max_size).truncate_object(@error)
|
31
27
|
end
|
32
28
|
|
33
29
|
context "when long" do
|
@@ -36,11 +32,6 @@ RSpec.describe Airbrake::PayloadTruncator do
|
|
36
32
|
it "truncates the backtrace to the max size" do
|
37
33
|
expect(@error[:backtrace].size).to eq(1000)
|
38
34
|
end
|
39
|
-
|
40
|
-
it "logs the about the number of truncated frames" do
|
41
|
-
expect(@stdout.string).
|
42
|
-
to match(/INFO -- .+ dropped 1003 frame\(s\) from AirbrakeTestError/)
|
43
|
-
end
|
44
35
|
end
|
45
36
|
|
46
37
|
context "when short" do
|
@@ -49,17 +40,17 @@ RSpec.describe Airbrake::PayloadTruncator do
|
|
49
40
|
it "does not truncate the backtrace" do
|
50
41
|
expect(@error[:backtrace].size).to eq(size)
|
51
42
|
end
|
52
|
-
|
53
|
-
it "doesn't log anything" do
|
54
|
-
expect(@stdout.string).to be_empty
|
55
|
-
end
|
56
43
|
end
|
57
44
|
end
|
58
45
|
|
59
46
|
describe "error message" do
|
47
|
+
let(:error) do
|
48
|
+
{ type: 'AirbrakeTestError', message: 'App crashed!', backtrace: [] }
|
49
|
+
end
|
50
|
+
|
60
51
|
before do
|
61
52
|
@error = error.merge(message: message)
|
62
|
-
described_class.new(max_size
|
53
|
+
described_class.new(max_size).truncate_object(@error)
|
63
54
|
end
|
64
55
|
|
65
56
|
context "when long" do
|
@@ -68,11 +59,6 @@ RSpec.describe Airbrake::PayloadTruncator do
|
|
68
59
|
it "truncates the message" do
|
69
60
|
expect(@error[:message].length).to eq(max_len)
|
70
61
|
end
|
71
|
-
|
72
|
-
it "logs about the truncated string" do
|
73
|
-
expect(@stdout.string).
|
74
|
-
to match(/INFO -- .+ truncated the message of AirbrakeTestError/)
|
75
|
-
end
|
76
62
|
end
|
77
63
|
|
78
64
|
context "when short" do
|
@@ -82,15 +68,9 @@ RSpec.describe Airbrake::PayloadTruncator do
|
|
82
68
|
it "doesn't truncate the message" do
|
83
69
|
expect(@error[:message].length).to eq(msg_len)
|
84
70
|
end
|
85
|
-
|
86
|
-
it "doesn't log about the truncated string" do
|
87
|
-
expect(@stdout.string).to be_empty
|
88
|
-
end
|
89
71
|
end
|
90
72
|
end
|
91
|
-
end
|
92
73
|
|
93
|
-
describe "#truncate_object" do
|
94
74
|
describe "given a hash with short values" do
|
95
75
|
let(:params) do
|
96
76
|
{ bingo: 'bango', bongo: 'bish', bash: 'bosh' }
|
@@ -270,7 +250,7 @@ RSpec.describe Airbrake::PayloadTruncator do
|
|
270
250
|
|
271
251
|
context "with strings that equal to max_size" do
|
272
252
|
before do
|
273
|
-
@truncator = described_class.new(max_size
|
253
|
+
@truncator = described_class.new(max_size)
|
274
254
|
end
|
275
255
|
|
276
256
|
let(:params) { { unicode: '1111' } }
|
@@ -399,7 +379,7 @@ RSpec.describe Airbrake::PayloadTruncator do
|
|
399
379
|
|
400
380
|
describe "unicode payload" do
|
401
381
|
before do
|
402
|
-
@truncator = described_class.new(max_size - 1
|
382
|
+
@truncator = described_class.new(max_size - 1)
|
403
383
|
end
|
404
384
|
|
405
385
|
describe "truncation" do
|