airbrake-ruby 4.6.0 → 6.2.2
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 +5 -5
- data/lib/airbrake-ruby/async_sender.rb +24 -109
- data/lib/airbrake-ruby/backlog.rb +123 -0
- data/lib/airbrake-ruby/backtrace.rb +8 -7
- data/lib/airbrake-ruby/benchmark.rb +1 -1
- data/lib/airbrake-ruby/code_hunk.rb +1 -1
- data/lib/airbrake-ruby/config/processor.rb +77 -0
- data/lib/airbrake-ruby/config/validator.rb +9 -3
- data/lib/airbrake-ruby/config.rb +78 -19
- data/lib/airbrake-ruby/context.rb +51 -0
- data/lib/airbrake-ruby/deploy_notifier.rb +1 -1
- data/lib/airbrake-ruby/file_cache.rb +6 -0
- data/lib/airbrake-ruby/filter_chain.rb +18 -1
- data/lib/airbrake-ruby/filters/context_filter.rb +4 -5
- data/lib/airbrake-ruby/filters/dependency_filter.rb +1 -0
- data/lib/airbrake-ruby/filters/exception_attributes_filter.rb +3 -3
- data/lib/airbrake-ruby/filters/gem_root_filter.rb +1 -0
- data/lib/airbrake-ruby/filters/git_last_checkout_filter.rb +7 -7
- data/lib/airbrake-ruby/filters/git_repository_filter.rb +11 -2
- data/lib/airbrake-ruby/filters/git_revision_filter.rb +3 -1
- data/lib/airbrake-ruby/filters/{keys_whitelist.rb → keys_allowlist.rb} +3 -3
- data/lib/airbrake-ruby/filters/{keys_blacklist.rb → keys_blocklist.rb} +3 -3
- data/lib/airbrake-ruby/filters/keys_filter.rb +41 -22
- data/lib/airbrake-ruby/filters/root_directory_filter.rb +1 -0
- data/lib/airbrake-ruby/filters/sql_filter.rb +35 -11
- data/lib/airbrake-ruby/filters/system_exit_filter.rb +1 -0
- data/lib/airbrake-ruby/filters/thread_filter.rb +6 -5
- data/lib/airbrake-ruby/grouppable.rb +12 -0
- data/lib/airbrake-ruby/ignorable.rb +1 -2
- data/lib/airbrake-ruby/inspectable.rb +2 -2
- data/lib/airbrake-ruby/loggable.rb +1 -1
- data/lib/airbrake-ruby/mergeable.rb +12 -0
- data/lib/airbrake-ruby/monotonic_time.rb +6 -1
- data/lib/airbrake-ruby/nested_exception.rb +22 -1
- data/lib/airbrake-ruby/notice.rb +12 -17
- data/lib/airbrake-ruby/notice_notifier.rb +15 -7
- data/lib/airbrake-ruby/performance_breakdown.rb +16 -9
- data/lib/airbrake-ruby/performance_notifier.rb +106 -54
- data/lib/airbrake-ruby/promise.rb +1 -0
- data/lib/airbrake-ruby/query.rb +20 -14
- data/lib/airbrake-ruby/queue.rb +65 -0
- data/lib/airbrake-ruby/remote_settings/callback.rb +44 -0
- data/lib/airbrake-ruby/remote_settings/settings_data.rb +116 -0
- data/lib/airbrake-ruby/remote_settings.rb +128 -0
- data/lib/airbrake-ruby/request.rb +14 -11
- data/lib/airbrake-ruby/response.rb +56 -5
- data/lib/airbrake-ruby/stat.rb +27 -34
- data/lib/airbrake-ruby/sync_sender.rb +43 -11
- data/lib/airbrake-ruby/tdigest.rb +52 -66
- data/lib/airbrake-ruby/thread_pool.rb +139 -0
- data/lib/airbrake-ruby/time_truncate.rb +2 -2
- data/lib/airbrake-ruby/timed_trace.rb +1 -3
- data/lib/airbrake-ruby/truncator.rb +10 -4
- data/lib/airbrake-ruby/version.rb +11 -1
- data/lib/airbrake-ruby.rb +157 -78
- metadata +122 -116
- data/spec/airbrake_spec.rb +0 -324
- data/spec/async_sender_spec.rb +0 -155
- data/spec/backtrace_spec.rb +0 -427
- data/spec/benchmark_spec.rb +0 -33
- data/spec/code_hunk_spec.rb +0 -115
- data/spec/config/validator_spec.rb +0 -184
- data/spec/config_spec.rb +0 -154
- data/spec/deploy_notifier_spec.rb +0 -48
- data/spec/file_cache.rb +0 -36
- data/spec/filter_chain_spec.rb +0 -92
- data/spec/filters/context_filter_spec.rb +0 -23
- data/spec/filters/dependency_filter_spec.rb +0 -12
- data/spec/filters/exception_attributes_filter_spec.rb +0 -50
- data/spec/filters/gem_root_filter_spec.rb +0 -41
- data/spec/filters/git_last_checkout_filter_spec.rb +0 -46
- data/spec/filters/git_repository_filter.rb +0 -61
- data/spec/filters/git_revision_filter_spec.rb +0 -126
- data/spec/filters/keys_blacklist_spec.rb +0 -225
- data/spec/filters/keys_whitelist_spec.rb +0 -194
- data/spec/filters/root_directory_filter_spec.rb +0 -39
- data/spec/filters/sql_filter_spec.rb +0 -219
- data/spec/filters/system_exit_filter_spec.rb +0 -14
- data/spec/filters/thread_filter_spec.rb +0 -277
- data/spec/fixtures/notroot.txt +0 -7
- data/spec/fixtures/project_root/code.rb +0 -221
- data/spec/fixtures/project_root/empty_file.rb +0 -0
- data/spec/fixtures/project_root/long_line.txt +0 -1
- data/spec/fixtures/project_root/short_file.rb +0 -3
- data/spec/fixtures/project_root/vendor/bundle/ignored_file.rb +0 -5
- data/spec/helpers.rb +0 -9
- data/spec/ignorable_spec.rb +0 -14
- data/spec/inspectable_spec.rb +0 -45
- data/spec/monotonic_time_spec.rb +0 -12
- data/spec/nested_exception_spec.rb +0 -73
- data/spec/notice_notifier_spec/options_spec.rb +0 -259
- data/spec/notice_notifier_spec.rb +0 -356
- data/spec/notice_spec.rb +0 -296
- data/spec/performance_breakdown_spec.rb +0 -12
- data/spec/performance_notifier_spec.rb +0 -435
- data/spec/promise_spec.rb +0 -197
- data/spec/query_spec.rb +0 -11
- data/spec/request_spec.rb +0 -11
- data/spec/response_spec.rb +0 -88
- data/spec/spec_helper.rb +0 -100
- data/spec/stashable_spec.rb +0 -23
- data/spec/stat_spec.rb +0 -47
- data/spec/sync_sender_spec.rb +0 -133
- data/spec/tdigest_spec.rb +0 -230
- data/spec/time_truncate_spec.rb +0 -13
- data/spec/timed_trace_spec.rb +0 -125
- data/spec/truncator_spec.rb +0 -238
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
RSpec.describe Airbrake::Filters::ExceptionAttributesFilter do
|
|
2
|
-
describe "#call" do
|
|
3
|
-
let(:notice) { Airbrake::Notice.new(ex) }
|
|
4
|
-
|
|
5
|
-
context "when #to_airbrake returns a non-Hash object" do
|
|
6
|
-
let(:ex) do
|
|
7
|
-
Class.new(AirbrakeTestError) do
|
|
8
|
-
def to_airbrake
|
|
9
|
-
Object.new
|
|
10
|
-
end
|
|
11
|
-
end.new
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
it "doesn't raise" do
|
|
15
|
-
expect { subject.call(notice) }.not_to raise_error
|
|
16
|
-
expect(notice[:params]).to be_empty
|
|
17
|
-
end
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
context "when #to_airbrake errors out" do
|
|
21
|
-
let(:ex) do
|
|
22
|
-
Class.new(AirbrakeTestError) do
|
|
23
|
-
def to_airbrake
|
|
24
|
-
1 / 0
|
|
25
|
-
end
|
|
26
|
-
end.new
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
it "doesn't raise" do
|
|
30
|
-
expect { subject.call(notice) }.not_to raise_error
|
|
31
|
-
expect(notice[:params]).to be_empty
|
|
32
|
-
end
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
context "when #to_airbrake returns a hash" do
|
|
36
|
-
let(:ex) do
|
|
37
|
-
Class.new(AirbrakeTestError) do
|
|
38
|
-
def to_airbrake
|
|
39
|
-
{ params: { foo: '1' } }
|
|
40
|
-
end
|
|
41
|
-
end.new
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
it "merges parameters with the notice" do
|
|
45
|
-
subject.call(notice)
|
|
46
|
-
expect(notice[:params]).to eq(foo: '1')
|
|
47
|
-
end
|
|
48
|
-
end
|
|
49
|
-
end
|
|
50
|
-
end
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
RSpec.describe Airbrake::Filters::GemRootFilter do
|
|
2
|
-
let(:notice) { Airbrake::Notice.new(AirbrakeTestError.new) }
|
|
3
|
-
let(:root1) { '/my/gem/root' }
|
|
4
|
-
let(:root2) { '/my/other/gem/root' }
|
|
5
|
-
|
|
6
|
-
before { Gem.path << root1 << root2 }
|
|
7
|
-
after { 2.times { Gem.path.pop } }
|
|
8
|
-
|
|
9
|
-
it "replaces gem root in the backtrace with a label" do
|
|
10
|
-
# rubocop:disable Metrics/LineLength
|
|
11
|
-
notice[:errors].first[:backtrace] = [
|
|
12
|
-
{ file: "/home/kyrylo/code/airbrake/ruby/spec/spec_helper.rb" },
|
|
13
|
-
{ file: "#{root1}/gems/rspec-core-3.3.2/lib/rspec/core/configuration.rb" },
|
|
14
|
-
{ file: "/opt/rubies/ruby-2.2.2/lib/ruby/2.2.0/rubygems/core_ext/kernel_require.rb" },
|
|
15
|
-
{ file: "#{root2}/gems/rspec-core-3.3.2/exe/rspec" }
|
|
16
|
-
]
|
|
17
|
-
# rubocop:enable Metrics/LineLength
|
|
18
|
-
|
|
19
|
-
subject.call(notice)
|
|
20
|
-
|
|
21
|
-
# rubocop:disable Metrics/LineLength
|
|
22
|
-
expect(notice[:errors].first[:backtrace]).to(
|
|
23
|
-
eq(
|
|
24
|
-
[
|
|
25
|
-
{ file: "/home/kyrylo/code/airbrake/ruby/spec/spec_helper.rb" },
|
|
26
|
-
{ file: "/GEM_ROOT/gems/rspec-core-3.3.2/lib/rspec/core/configuration.rb" },
|
|
27
|
-
{ file: "/opt/rubies/ruby-2.2.2/lib/ruby/2.2.0/rubygems/core_ext/kernel_require.rb" },
|
|
28
|
-
{ file: "/GEM_ROOT/gems/rspec-core-3.3.2/exe/rspec" }
|
|
29
|
-
]
|
|
30
|
-
)
|
|
31
|
-
)
|
|
32
|
-
# rubocop:enable Metrics/LineLength
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
it "does not filter file when it is nil" do
|
|
36
|
-
expect(notice[:errors].first[:file]).to be_nil
|
|
37
|
-
expect { subject.call(notice) }.not_to(
|
|
38
|
-
change { notice[:errors].first[:file] }
|
|
39
|
-
)
|
|
40
|
-
end
|
|
41
|
-
end
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
RSpec.describe Airbrake::Filters::GitLastCheckoutFilter do
|
|
2
|
-
subject { described_class.new('.') }
|
|
3
|
-
|
|
4
|
-
let(:notice) { Airbrake::Notice.new(AirbrakeTestError.new) }
|
|
5
|
-
|
|
6
|
-
context "when context/lastCheckout is defined" do
|
|
7
|
-
it "doesn't attach anything to context/lastCheckout" do
|
|
8
|
-
notice[:context][:lastCheckout] = '123'
|
|
9
|
-
subject.call(notice)
|
|
10
|
-
expect(notice[:context][:lastCheckout]).to eq('123')
|
|
11
|
-
end
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
context "when .git directory doesn't exist" do
|
|
15
|
-
subject { described_class.new('root/dir') }
|
|
16
|
-
|
|
17
|
-
it "doesn't attach anything to context/lastCheckout" do
|
|
18
|
-
subject.call(notice)
|
|
19
|
-
expect(notice[:context][:lastCheckout]).to be_nil
|
|
20
|
-
end
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
context "when .git directory exists" do
|
|
24
|
-
before { subject.call(notice) }
|
|
25
|
-
|
|
26
|
-
it "attaches last checkouted username" do
|
|
27
|
-
expect(notice[:context][:lastCheckout][:username]).not_to be_empty
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
it "attaches last checkouted email" do
|
|
31
|
-
expect(notice[:context][:lastCheckout][:email]).to(
|
|
32
|
-
match(/\A\w+[\w.-]*@\w+\.?\w+?\z/)
|
|
33
|
-
)
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
it "attaches last checkouted revision" do
|
|
37
|
-
expect(notice[:context][:lastCheckout][:revision]).not_to be_empty
|
|
38
|
-
expect(notice[:context][:lastCheckout][:revision].size).to eq(40)
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
it "attaches last checkouted time" do
|
|
42
|
-
expect(notice[:context][:lastCheckout][:time]).not_to be_empty
|
|
43
|
-
expect(notice[:context][:lastCheckout][:time].size).to eq(25)
|
|
44
|
-
end
|
|
45
|
-
end
|
|
46
|
-
end
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
RSpec.describe Airbrake::Filters::GitRepositoryFilter do
|
|
2
|
-
subject { described_class.new('.') }
|
|
3
|
-
|
|
4
|
-
let(:notice) do
|
|
5
|
-
Airbrake::Notice.new(Airbrake::Config.new, AirbrakeTestError.new)
|
|
6
|
-
end
|
|
7
|
-
|
|
8
|
-
describe "#initialize" do
|
|
9
|
-
it "parses standard git version" do
|
|
10
|
-
allow_any_instance_of(Kernel)
|
|
11
|
-
.to receive(:`).and_return('git version 2.18.0')
|
|
12
|
-
expect { subject }.not_to raise_error
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
it "parses release candidate git version" do
|
|
16
|
-
allow_any_instance_of(Kernel)
|
|
17
|
-
.to receive(:`).and_return('git version 2.21.0-rc0')
|
|
18
|
-
expect { subject }.not_to raise_error
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
it "parses git version with brackets" do
|
|
22
|
-
allow_any_instance_of(Kernel)
|
|
23
|
-
.to receive(:`).and_return('git version 2.17.2 (Apple Git-113)')
|
|
24
|
-
expect { subject }.not_to raise_error
|
|
25
|
-
end
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
context "when context/repository is defined" do
|
|
29
|
-
it "doesn't attach anything to context/repository" do
|
|
30
|
-
notice[:context][:repository] = 'git@github.com:kyrylo/test.git'
|
|
31
|
-
subject.call(notice)
|
|
32
|
-
expect(notice[:context][:repository]).to eq('git@github.com:kyrylo/test.git')
|
|
33
|
-
end
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
context "when .git directory doesn't exist" do
|
|
37
|
-
subject { described_class.new('root/dir') }
|
|
38
|
-
|
|
39
|
-
it "doesn't attach anything to context/repository" do
|
|
40
|
-
subject.call(notice)
|
|
41
|
-
expect(notice[:context][:repository]).to be_nil
|
|
42
|
-
end
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
context "when .git directory exists" do
|
|
46
|
-
it "attaches context/repository" do
|
|
47
|
-
subject.call(notice)
|
|
48
|
-
expect(notice[:context][:repository]).to eq(
|
|
49
|
-
'ssh://git@github.com/airbrake/airbrake-ruby.git'
|
|
50
|
-
)
|
|
51
|
-
end
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
context "when git is not in PATH" do
|
|
55
|
-
it "does not attach context/repository" do
|
|
56
|
-
ENV['PATH'] = ''
|
|
57
|
-
subject.call(notice)
|
|
58
|
-
expect(notice[:context][:repository]).to be_nil
|
|
59
|
-
end
|
|
60
|
-
end
|
|
61
|
-
end
|
|
@@ -1,126 +0,0 @@
|
|
|
1
|
-
RSpec.describe Airbrake::Filters::GitRevisionFilter do
|
|
2
|
-
subject { described_class.new('root/dir') }
|
|
3
|
-
|
|
4
|
-
# 'let!', not 'let' to make sure Notice doesn't call File.exist? with
|
|
5
|
-
# unexpected arguments.
|
|
6
|
-
let!(:notice) { Airbrake::Notice.new(AirbrakeTestError.new) }
|
|
7
|
-
|
|
8
|
-
context "when context/revision is defined" do
|
|
9
|
-
it "doesn't attach anything to context/revision" do
|
|
10
|
-
notice[:context][:revision] = '1.2.3'
|
|
11
|
-
subject.call(notice)
|
|
12
|
-
expect(notice[:context][:revision]).to eq('1.2.3')
|
|
13
|
-
end
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
context "when .git directory doesn't exist" do
|
|
17
|
-
it "doesn't attach anything to context/revision" do
|
|
18
|
-
subject.call(notice)
|
|
19
|
-
expect(notice[:context][:revision]).to be_nil
|
|
20
|
-
end
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
context "when .git directory exists" do
|
|
24
|
-
before do
|
|
25
|
-
expect(File).to receive(:exist?).with('root/dir/.git').and_return(true)
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
context "and when HEAD doesn't exist" do
|
|
29
|
-
before do
|
|
30
|
-
expect(File).to receive(:exist?).with('root/dir/.git/HEAD').and_return(false)
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
it "doesn't attach anything to context/revision" do
|
|
34
|
-
subject.call(notice)
|
|
35
|
-
expect(notice[:context][:revision]).to be_nil
|
|
36
|
-
end
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
context "and when HEAD exists" do
|
|
40
|
-
before do
|
|
41
|
-
expect(File).to receive(:exist?).with('root/dir/.git/HEAD').and_return(true)
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
context "and also when HEAD doesn't start with 'ref: '" do
|
|
45
|
-
before do
|
|
46
|
-
expect(File).to(
|
|
47
|
-
receive(:read).with('root/dir/.git/HEAD').and_return('refs/foo')
|
|
48
|
-
)
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
it "attaches the content of HEAD to context/revision" do
|
|
52
|
-
subject.call(notice)
|
|
53
|
-
expect(notice[:context][:revision]).to eq('refs/foo')
|
|
54
|
-
end
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
context "and also when HEAD starts with 'ref: " do
|
|
58
|
-
before do
|
|
59
|
-
expect(File).to(
|
|
60
|
-
receive(:read).with('root/dir/.git/HEAD').and_return("ref: refs/foo\n")
|
|
61
|
-
)
|
|
62
|
-
end
|
|
63
|
-
|
|
64
|
-
context "when the ref exists" do
|
|
65
|
-
before do
|
|
66
|
-
expect(File).to(
|
|
67
|
-
receive(:exist?).with('root/dir/.git/refs/foo').and_return(true)
|
|
68
|
-
)
|
|
69
|
-
expect(File).to(
|
|
70
|
-
receive(:read).with('root/dir/.git/refs/foo').and_return("d34db33f\n")
|
|
71
|
-
)
|
|
72
|
-
end
|
|
73
|
-
|
|
74
|
-
it "attaches the revision from the ref to context/revision" do
|
|
75
|
-
subject.call(notice)
|
|
76
|
-
expect(notice[:context][:revision]).to eq('d34db33f')
|
|
77
|
-
end
|
|
78
|
-
end
|
|
79
|
-
|
|
80
|
-
context "when the ref doesn't exist" do
|
|
81
|
-
before do
|
|
82
|
-
expect(File).to(
|
|
83
|
-
receive(:exist?).with('root/dir/.git/refs/foo').and_return(false)
|
|
84
|
-
)
|
|
85
|
-
end
|
|
86
|
-
|
|
87
|
-
context "and when '.git/packed-refs' exists" do
|
|
88
|
-
before do
|
|
89
|
-
expect(File).to(
|
|
90
|
-
receive(:exist?).with('root/dir/.git/packed-refs').and_return(true)
|
|
91
|
-
)
|
|
92
|
-
expect(File).to(
|
|
93
|
-
receive(:readlines).with('root/dir/.git/packed-refs').and_return(
|
|
94
|
-
[
|
|
95
|
-
"# pack-refs with: peeled fully-peeled\n",
|
|
96
|
-
"ccb316eecff79c7528d1ad43e5fa165f7a44d52e refs/tags/v3.0.30\n",
|
|
97
|
-
"^d358900f73ee5bfd6ca3a592cf23ac6e82df83c1",
|
|
98
|
-
"d34db33f refs/foo\n"
|
|
99
|
-
]
|
|
100
|
-
)
|
|
101
|
-
)
|
|
102
|
-
end
|
|
103
|
-
|
|
104
|
-
it "attaches the revision from 'packed-refs' to context/revision" do
|
|
105
|
-
subject.call(notice)
|
|
106
|
-
expect(notice[:context][:revision]).to eq('d34db33f')
|
|
107
|
-
end
|
|
108
|
-
end
|
|
109
|
-
|
|
110
|
-
context "and when '.git/packed-refs' doesn't exist" do
|
|
111
|
-
before do
|
|
112
|
-
expect(File).to(
|
|
113
|
-
receive(:exist?).with('root/dir/.git/packed-refs').and_return(false)
|
|
114
|
-
)
|
|
115
|
-
end
|
|
116
|
-
|
|
117
|
-
it "attaches the content of HEAD to context/revision" do
|
|
118
|
-
subject.call(notice)
|
|
119
|
-
expect(notice[:context][:revision]).to eq('refs/foo')
|
|
120
|
-
end
|
|
121
|
-
end
|
|
122
|
-
end
|
|
123
|
-
end
|
|
124
|
-
end
|
|
125
|
-
end
|
|
126
|
-
end
|
|
@@ -1,225 +0,0 @@
|
|
|
1
|
-
RSpec.describe Airbrake::Filters::KeysBlacklist do
|
|
2
|
-
subject { described_class.new(patterns) }
|
|
3
|
-
|
|
4
|
-
let(:notice) { Airbrake::Notice.new(AirbrakeTestError.new) }
|
|
5
|
-
|
|
6
|
-
shared_examples 'pattern matching' do |patts, params|
|
|
7
|
-
let(:patterns) { patts }
|
|
8
|
-
|
|
9
|
-
it "filters out the matching values" do
|
|
10
|
-
notice[:params] = params.first
|
|
11
|
-
subject.call(notice)
|
|
12
|
-
expect(notice[:params]).to eq(params.last)
|
|
13
|
-
end
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
context "when a pattern is a Regexp" do
|
|
17
|
-
include_examples(
|
|
18
|
-
'pattern matching',
|
|
19
|
-
[/\Abon/],
|
|
20
|
-
[
|
|
21
|
-
{ bongo: 'bango' },
|
|
22
|
-
{ bongo: '[Filtered]' }
|
|
23
|
-
]
|
|
24
|
-
)
|
|
25
|
-
|
|
26
|
-
context "and when a key is a hash" do
|
|
27
|
-
let(:patterns) { [/bango/] }
|
|
28
|
-
|
|
29
|
-
# https://github.com/airbrake/airbrake/issues/739
|
|
30
|
-
it "doesn't fail" do
|
|
31
|
-
notice[:params] = { bingo: { {} => 'unfiltered' } }
|
|
32
|
-
expect { subject.call(notice) }.not_to raise_error
|
|
33
|
-
end
|
|
34
|
-
end
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
context "when a pattern is a Symbol" do
|
|
38
|
-
include_examples(
|
|
39
|
-
'pattern matching',
|
|
40
|
-
[:bingo],
|
|
41
|
-
[
|
|
42
|
-
{ bingo: 'bango' },
|
|
43
|
-
{ bingo: '[Filtered]' }
|
|
44
|
-
]
|
|
45
|
-
)
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
context "when a pattern is a String" do
|
|
49
|
-
include_examples(
|
|
50
|
-
'pattern matching',
|
|
51
|
-
['bingo'],
|
|
52
|
-
[
|
|
53
|
-
{ bingo: 'bango' },
|
|
54
|
-
{ bingo: '[Filtered]' }
|
|
55
|
-
]
|
|
56
|
-
)
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
context "when a pattern is a Array of Hash" do
|
|
60
|
-
include_examples(
|
|
61
|
-
'pattern matching',
|
|
62
|
-
['bingo'],
|
|
63
|
-
[
|
|
64
|
-
{ array: [{ bingo: 'bango' }, []] },
|
|
65
|
-
{ array: [{ bingo: '[Filtered]' }, []] }
|
|
66
|
-
]
|
|
67
|
-
)
|
|
68
|
-
end
|
|
69
|
-
|
|
70
|
-
context "when a Proc pattern was provided" do
|
|
71
|
-
context "along with normal keys" do
|
|
72
|
-
include_examples(
|
|
73
|
-
'pattern matching',
|
|
74
|
-
[proc { 'bongo' }, :bash],
|
|
75
|
-
[
|
|
76
|
-
{ bingo: 'bango', bongo: 'bish', bash: 'bosh' },
|
|
77
|
-
{ bingo: 'bango', bongo: '[Filtered]', bash: '[Filtered]' }
|
|
78
|
-
]
|
|
79
|
-
)
|
|
80
|
-
end
|
|
81
|
-
|
|
82
|
-
context "which doesn't return an array of keys" do
|
|
83
|
-
include_examples(
|
|
84
|
-
'pattern matching',
|
|
85
|
-
[proc { Object.new }],
|
|
86
|
-
[
|
|
87
|
-
{ bingo: 'bango', bongo: 'bish' },
|
|
88
|
-
{ bingo: 'bango', bongo: 'bish' }
|
|
89
|
-
]
|
|
90
|
-
)
|
|
91
|
-
|
|
92
|
-
it "logs an error" do
|
|
93
|
-
expect(Airbrake::Loggable.instance).to receive(:error).with(
|
|
94
|
-
/KeysBlacklist is invalid.+patterns: \[#<Object:.+>\]/
|
|
95
|
-
)
|
|
96
|
-
keys_blacklist = described_class.new(patterns)
|
|
97
|
-
keys_blacklist.call(notice)
|
|
98
|
-
end
|
|
99
|
-
end
|
|
100
|
-
|
|
101
|
-
context "which returns another Proc" do
|
|
102
|
-
let(:patterns) { [proc { proc { ['bingo'] } }] }
|
|
103
|
-
|
|
104
|
-
context "and when the filter is called once" do
|
|
105
|
-
it "logs an error" do
|
|
106
|
-
expect(Airbrake::Loggable.instance).to receive(:error).with(
|
|
107
|
-
/KeysBlacklist is invalid.+patterns: \[#<Proc:.+>\]/
|
|
108
|
-
)
|
|
109
|
-
keys_blacklist = described_class.new(patterns)
|
|
110
|
-
keys_blacklist.call(notice)
|
|
111
|
-
end
|
|
112
|
-
end
|
|
113
|
-
|
|
114
|
-
context "and when the filter is called twice" do
|
|
115
|
-
it "unwinds procs and filters keys" do
|
|
116
|
-
notice[:params] = { bingo: 'bango', bongo: 'bish' }
|
|
117
|
-
2.times { subject.call(notice) }
|
|
118
|
-
expect(notice[:params]).to eq(bingo: '[Filtered]', bongo: 'bish')
|
|
119
|
-
end
|
|
120
|
-
end
|
|
121
|
-
end
|
|
122
|
-
end
|
|
123
|
-
|
|
124
|
-
context "when a pattern is invalid" do
|
|
125
|
-
include_examples(
|
|
126
|
-
'pattern matching',
|
|
127
|
-
[Object.new],
|
|
128
|
-
[
|
|
129
|
-
{ bingo: 'bango', bongo: 'bish' },
|
|
130
|
-
{ bingo: 'bango', bongo: 'bish' }
|
|
131
|
-
]
|
|
132
|
-
)
|
|
133
|
-
|
|
134
|
-
it "logs an error" do
|
|
135
|
-
expect(Airbrake::Loggable.instance).to receive(:error).with(
|
|
136
|
-
/KeysBlacklist is invalid.+patterns: \[#<Object:.+>\]/
|
|
137
|
-
)
|
|
138
|
-
keys_blacklist = described_class.new(patterns)
|
|
139
|
-
keys_blacklist.call(notice)
|
|
140
|
-
end
|
|
141
|
-
end
|
|
142
|
-
|
|
143
|
-
context "when a value contains a nested hash" do
|
|
144
|
-
context "and it is non-recursive" do
|
|
145
|
-
include_examples(
|
|
146
|
-
'pattern matching',
|
|
147
|
-
['bish'],
|
|
148
|
-
[
|
|
149
|
-
{ bongo: { bish: 'bash' } },
|
|
150
|
-
{ bongo: { bish: '[Filtered]' } }
|
|
151
|
-
]
|
|
152
|
-
)
|
|
153
|
-
end
|
|
154
|
-
|
|
155
|
-
context "and it is recursive" do
|
|
156
|
-
bongo = { bingo: {} }
|
|
157
|
-
bongo[:bingo][:bango] = bongo
|
|
158
|
-
|
|
159
|
-
include_examples(
|
|
160
|
-
'pattern matching',
|
|
161
|
-
['bango'],
|
|
162
|
-
[
|
|
163
|
-
bongo,
|
|
164
|
-
{ bingo: { bango: '[Filtered]' } }
|
|
165
|
-
]
|
|
166
|
-
)
|
|
167
|
-
end
|
|
168
|
-
end
|
|
169
|
-
|
|
170
|
-
describe "context payload" do
|
|
171
|
-
context "when a URL with query params is present" do
|
|
172
|
-
let(:patterns) { ['bish'] }
|
|
173
|
-
|
|
174
|
-
it "filters the params" do
|
|
175
|
-
notice[:context][:url] =
|
|
176
|
-
'http://localhost:3000/crash?foo=bar&baz=bongo&bish=bash&color=%23FFAAFF'
|
|
177
|
-
|
|
178
|
-
subject.call(notice)
|
|
179
|
-
expect(notice[:context][:url]).to(
|
|
180
|
-
eq 'http://localhost:3000/crash?foo=bar&baz=bongo&bish=[Filtered]&color=%23FFAAFF'
|
|
181
|
-
)
|
|
182
|
-
end
|
|
183
|
-
end
|
|
184
|
-
|
|
185
|
-
context "when the user key is present" do
|
|
186
|
-
let(:patterns) { ['user'] }
|
|
187
|
-
|
|
188
|
-
it "filters out the user" do
|
|
189
|
-
notice[:context][:user] = { id: 1337, name: 'Bingo Bango' }
|
|
190
|
-
subject.call(notice)
|
|
191
|
-
expect(notice[:context][:user]).to eq('[Filtered]')
|
|
192
|
-
end
|
|
193
|
-
end
|
|
194
|
-
|
|
195
|
-
context "and when it is a hash" do
|
|
196
|
-
let(:patterns) { ['name'] }
|
|
197
|
-
|
|
198
|
-
it "filters out individual user fields" do
|
|
199
|
-
notice[:context][:user] = { id: 1337, name: 'Bingo Bango' }
|
|
200
|
-
subject.call(notice)
|
|
201
|
-
expect(notice[:context][:user][:name]).to eq('[Filtered]')
|
|
202
|
-
end
|
|
203
|
-
end
|
|
204
|
-
end
|
|
205
|
-
|
|
206
|
-
context "when the headers key is present" do
|
|
207
|
-
let(:patterns) { ['headers'] }
|
|
208
|
-
|
|
209
|
-
it "filters out the headers" do
|
|
210
|
-
notice[:context][:headers] = { 'HTTP_COOKIE' => 'banana' }
|
|
211
|
-
subject.call(notice)
|
|
212
|
-
expect(notice[:context][:headers]).to eq('[Filtered]')
|
|
213
|
-
end
|
|
214
|
-
|
|
215
|
-
context "and when it is a hash" do
|
|
216
|
-
let(:patterns) { ['HTTP_COOKIE'] }
|
|
217
|
-
|
|
218
|
-
it "filters out individual header fields" do
|
|
219
|
-
notice[:context][:headers] = { 'HTTP_COOKIE' => 'banana' }
|
|
220
|
-
subject.call(notice)
|
|
221
|
-
expect(notice[:context][:headers]['HTTP_COOKIE']).to eq('[Filtered]')
|
|
222
|
-
end
|
|
223
|
-
end
|
|
224
|
-
end
|
|
225
|
-
end
|