airbrake-ruby 3.2.6-java → 4.0.0-java

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.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/lib/airbrake-ruby.rb +31 -138
  3. data/lib/airbrake-ruby/async_sender.rb +20 -8
  4. data/lib/airbrake-ruby/backtrace.rb +15 -13
  5. data/lib/airbrake-ruby/code_hunk.rb +2 -4
  6. data/lib/airbrake-ruby/config.rb +8 -38
  7. data/lib/airbrake-ruby/deploy_notifier.rb +4 -17
  8. data/lib/airbrake-ruby/filters/exception_attributes_filter.rb +5 -4
  9. data/lib/airbrake-ruby/filters/git_last_checkout_filter.rb +6 -4
  10. data/lib/airbrake-ruby/filters/keys_blacklist.rb +0 -1
  11. data/lib/airbrake-ruby/filters/keys_filter.rb +4 -4
  12. data/lib/airbrake-ruby/filters/keys_whitelist.rb +0 -1
  13. data/lib/airbrake-ruby/loggable.rb +31 -0
  14. data/lib/airbrake-ruby/nested_exception.rb +2 -3
  15. data/lib/airbrake-ruby/notice.rb +6 -6
  16. data/lib/airbrake-ruby/notice_notifier.rb +11 -47
  17. data/lib/airbrake-ruby/performance_notifier.rb +6 -18
  18. data/lib/airbrake-ruby/response.rb +5 -2
  19. data/lib/airbrake-ruby/sync_sender.rb +8 -6
  20. data/lib/airbrake-ruby/version.rb +1 -1
  21. data/spec/airbrake_spec.rb +1 -143
  22. data/spec/async_sender_spec.rb +83 -90
  23. data/spec/backtrace_spec.rb +36 -47
  24. data/spec/code_hunk_spec.rb +12 -15
  25. data/spec/config_spec.rb +79 -96
  26. data/spec/deploy_notifier_spec.rb +3 -7
  27. data/spec/filter_chain_spec.rb +1 -3
  28. data/spec/filters/context_filter_spec.rb +1 -3
  29. data/spec/filters/dependency_filter_spec.rb +1 -3
  30. data/spec/filters/exception_attributes_filter_spec.rb +1 -14
  31. data/spec/filters/gem_root_filter_spec.rb +1 -4
  32. data/spec/filters/git_last_checkout_filter_spec.rb +3 -5
  33. data/spec/filters/git_revision_filter_spec.rb +1 -3
  34. data/spec/filters/keys_blacklist_spec.rb +14 -25
  35. data/spec/filters/keys_whitelist_spec.rb +14 -25
  36. data/spec/filters/root_directory_filter_spec.rb +1 -4
  37. data/spec/filters/system_exit_filter_spec.rb +2 -2
  38. data/spec/filters/thread_filter_spec.rb +1 -3
  39. data/spec/nested_exception_spec.rb +3 -5
  40. data/spec/notice_notifier_spec.rb +23 -20
  41. data/spec/notice_notifier_spec/options_spec.rb +20 -25
  42. data/spec/notice_spec.rb +13 -12
  43. data/spec/performance_notifier_spec.rb +19 -31
  44. data/spec/response_spec.rb +23 -17
  45. data/spec/sync_sender_spec.rb +26 -33
  46. metadata +2 -1
@@ -1,9 +1,5 @@
1
1
  RSpec.describe Airbrake::DeployNotifier do
2
- let(:user_params) { { project_id: 1, project_key: 'banana' } }
3
- let(:params) { {} }
4
- let(:config) { Airbrake::Config.new(user_params.merge(params)) }
5
-
6
- subject { described_class.new(config) }
2
+ before { Airbrake::Config.instance = Airbrake::Config.new(project_id: 1) }
7
3
 
8
4
  describe "#notify" do
9
5
  it "returns a promise" do
@@ -13,7 +9,7 @@ RSpec.describe Airbrake::DeployNotifier do
13
9
  end
14
10
 
15
11
  context "when environment is configured" do
16
- let(:params) { { environment: 'fooenv' } }
12
+ before { Airbrake::Config.instance.merge(environment: 'fooenv') }
17
13
 
18
14
  it "prefers the passed environment to the config env" do
19
15
  expect_any_instance_of(Airbrake::SyncSender).to receive(:send).with(
@@ -26,7 +22,7 @@ RSpec.describe Airbrake::DeployNotifier do
26
22
  end
27
23
 
28
24
  context "when environment is not configured" do
29
- let(:params) { { environment: 'fooenv' } }
25
+ before { Airbrake::Config.instance.merge(environment: 'fooenv') }
30
26
 
31
27
  it "sets the environment from the config" do
32
28
  expect_any_instance_of(Airbrake::SyncSender).to receive(:send).with(
@@ -1,7 +1,5 @@
1
1
  RSpec.describe Airbrake::FilterChain do
2
- let(:notice) do
3
- Airbrake::Notice.new(Airbrake::Config.new, AirbrakeTestError.new)
4
- end
2
+ let(:notice) { Airbrake::Notice.new(AirbrakeTestError.new) }
5
3
 
6
4
  describe "#refine" do
7
5
  let(:filter) do
@@ -1,7 +1,5 @@
1
1
  RSpec.describe Airbrake::Filters::ContextFilter do
2
- let(:notice) do
3
- Airbrake::Notice.new(Airbrake::Config.new, AirbrakeTestError.new)
4
- end
2
+ let(:notice) { Airbrake::Notice.new(AirbrakeTestError.new) }
5
3
 
6
4
  context "when the current context is empty" do
7
5
  it "doesn't merge anything with params" do
@@ -1,7 +1,5 @@
1
1
  RSpec.describe Airbrake::Filters::DependencyFilter do
2
- let(:notice) do
3
- Airbrake::Notice.new(Airbrake::Config.new, AirbrakeTestError.new)
4
- end
2
+ let(:notice) { Airbrake::Notice.new(AirbrakeTestError.new) }
5
3
 
6
4
  describe "#call" do
7
5
  it "attaches loaded dependencies to context/versions/dependencies" do
@@ -1,9 +1,6 @@
1
1
  RSpec.describe Airbrake::Filters::ExceptionAttributesFilter do
2
2
  describe "#call" do
3
- let(:out) { StringIO.new }
4
- let(:notice) { Airbrake::Notice.new(Airbrake::Config.new, ex) }
5
-
6
- subject { described_class.new(Logger.new(out)) }
3
+ let(:notice) { Airbrake::Notice.new(ex) }
7
4
 
8
5
  context "when #to_airbrake returns a non-Hash object" do
9
6
  let(:ex) do
@@ -18,11 +15,6 @@ RSpec.describe Airbrake::Filters::ExceptionAttributesFilter do
18
15
  expect { subject.call(notice) }.not_to raise_error
19
16
  expect(notice[:params]).to be_empty
20
17
  end
21
-
22
- it "logs the error" do
23
- expect { subject.call(notice) }.not_to raise_error
24
- expect(out.string).to match(/wanted Hash, got Object/)
25
- end
26
18
  end
27
19
 
28
20
  context "when #to_airbrake errors out" do
@@ -38,11 +30,6 @@ RSpec.describe Airbrake::Filters::ExceptionAttributesFilter do
38
30
  expect { subject.call(notice) }.not_to raise_error
39
31
  expect(notice[:params]).to be_empty
40
32
  end
41
-
42
- it "logs the error" do
43
- expect { subject.call(notice) }.not_to raise_error
44
- expect(out.string).to match(/#to_airbrake failed.+ZeroDivisionError/)
45
- end
46
33
  end
47
34
 
48
35
  context "when #to_airbrake returns a hash" do
@@ -1,8 +1,5 @@
1
1
  RSpec.describe Airbrake::Filters::GemRootFilter do
2
- let(:notice) do
3
- Airbrake::Notice.new(Airbrake::Config.new, AirbrakeTestError.new)
4
- end
5
-
2
+ let(:notice) { Airbrake::Notice.new(AirbrakeTestError.new) }
6
3
  let(:root1) { '/my/gem/root' }
7
4
  let(:root2) { '/my/other/gem/root' }
8
5
 
@@ -1,9 +1,7 @@
1
1
  RSpec.describe Airbrake::Filters::GitLastCheckoutFilter do
2
- subject { described_class.new(Logger.new(STDOUT), '.') }
2
+ subject { described_class.new('.') }
3
3
 
4
- let(:notice) do
5
- Airbrake::Notice.new(Airbrake::Config.new, AirbrakeTestError.new)
6
- end
4
+ let(:notice) { Airbrake::Notice.new(AirbrakeTestError.new) }
7
5
 
8
6
  context "when context/lastCheckout is defined" do
9
7
  it "doesn't attach anything to context/lastCheckout" do
@@ -14,7 +12,7 @@ RSpec.describe Airbrake::Filters::GitLastCheckoutFilter do
14
12
  end
15
13
 
16
14
  context "when .git directory doesn't exist" do
17
- subject { described_class.new(Logger.new(STDOUT), 'root/dir') }
15
+ subject { described_class.new('root/dir') }
18
16
 
19
17
  it "doesn't attach anything to context/lastCheckout" do
20
18
  subject.call(notice)
@@ -1,9 +1,7 @@
1
1
  RSpec.describe Airbrake::Filters::GitRevisionFilter do
2
2
  subject { described_class.new('root/dir') }
3
3
 
4
- let(:notice) do
5
- Airbrake::Notice.new(Airbrake::Config.new, AirbrakeTestError.new)
6
- end
4
+ let(:notice) { Airbrake::Notice.new(AirbrakeTestError.new) }
7
5
 
8
6
  context "when context/revision is defined" do
9
7
  it "doesn't attach anything to context/revision" do
@@ -1,9 +1,7 @@
1
1
  RSpec.describe Airbrake::Filters::KeysBlacklist do
2
- subject { described_class.new(Logger.new('/dev/null'), patterns) }
2
+ subject { described_class.new(patterns) }
3
3
 
4
- let(:notice) do
5
- Airbrake::Notice.new(Airbrake::Config.new, AirbrakeTestError.new)
6
- end
4
+ let(:notice) { Airbrake::Notice.new(AirbrakeTestError.new) }
7
5
 
8
6
  shared_examples 'pattern matching' do |patts, params|
9
7
  let(:patterns) { patts }
@@ -92,14 +90,11 @@ RSpec.describe Airbrake::Filters::KeysBlacklist do
92
90
  )
93
91
 
94
92
  it "logs an error" do
95
- out = StringIO.new
96
- logger = Logger.new(out)
97
- keys_blacklist = described_class.new(logger, patterns)
98
- keys_blacklist.call(notice)
99
-
100
- expect(out.string).to(
101
- match(/ERROR.+KeysBlacklist is invalid.+patterns: \[#<Object:.+>\]/)
93
+ expect(Airbrake::Loggable.instance).to receive(:error).with(
94
+ /KeysBlacklist is invalid.+patterns: \[#<Object:.+>\]/
102
95
  )
96
+ keys_blacklist = described_class.new(patterns)
97
+ keys_blacklist.call(notice)
103
98
  end
104
99
  end
105
100
 
@@ -108,14 +103,11 @@ RSpec.describe Airbrake::Filters::KeysBlacklist do
108
103
 
109
104
  context "and when the filter is called once" do
110
105
  it "logs an error" do
111
- out = StringIO.new
112
- logger = Logger.new(out)
113
- keys_blacklist = described_class.new(logger, patterns)
114
- keys_blacklist.call(notice)
115
-
116
- expect(out.string).to(
117
- match(/ERROR.+KeysBlacklist is invalid.+patterns: \[#<Proc:.+>\]/)
106
+ expect(Airbrake::Loggable.instance).to receive(:error).with(
107
+ /KeysBlacklist is invalid.+patterns: \[#<Proc:.+>\]/
118
108
  )
109
+ keys_blacklist = described_class.new(patterns)
110
+ keys_blacklist.call(notice)
119
111
  end
120
112
  end
121
113
 
@@ -140,14 +132,11 @@ RSpec.describe Airbrake::Filters::KeysBlacklist do
140
132
  )
141
133
 
142
134
  it "logs an error" do
143
- out = StringIO.new
144
- logger = Logger.new(out)
145
- keys_blacklist = described_class.new(logger, patterns)
146
- keys_blacklist.call(notice)
147
-
148
- expect(out.string).to(
149
- match(/ERROR.+KeysBlacklist is invalid.+patterns: \[#<Object:.+>\]/)
135
+ expect(Airbrake::Loggable.instance).to receive(:error).with(
136
+ /KeysBlacklist is invalid.+patterns: \[#<Object:.+>\]/
150
137
  )
138
+ keys_blacklist = described_class.new(patterns)
139
+ keys_blacklist.call(notice)
151
140
  end
152
141
  end
153
142
 
@@ -1,9 +1,7 @@
1
1
  RSpec.describe Airbrake::Filters::KeysWhitelist do
2
- subject { described_class.new(Logger.new('/dev/null'), patterns) }
2
+ subject { described_class.new(patterns) }
3
3
 
4
- let(:notice) do
5
- Airbrake::Notice.new(Airbrake::Config.new, AirbrakeTestError.new)
6
- end
4
+ let(:notice) { Airbrake::Notice.new(AirbrakeTestError.new) }
7
5
 
8
6
  shared_examples 'pattern matching' do |patts, params|
9
7
  let(:patterns) { patts }
@@ -71,14 +69,11 @@ RSpec.describe Airbrake::Filters::KeysWhitelist do
71
69
  )
72
70
 
73
71
  it "logs an error" do
74
- out = StringIO.new
75
- logger = Logger.new(out)
76
- keys_whitelist = described_class.new(logger, patterns)
77
- keys_whitelist.call(notice)
78
-
79
- expect(out.string).to(
80
- match(/ERROR.+KeysWhitelist is invalid.+patterns: \[#<Object:.+>\]/)
72
+ expect(Airbrake::Loggable.instance).to receive(:error).with(
73
+ /KeysWhitelist is invalid.+patterns: \[#<Object:.+>\]/
81
74
  )
75
+ keys_whitelist = described_class.new(patterns)
76
+ keys_whitelist.call(notice)
82
77
  end
83
78
  end
84
79
 
@@ -87,14 +82,11 @@ RSpec.describe Airbrake::Filters::KeysWhitelist do
87
82
 
88
83
  context "and when the filter is called once" do
89
84
  it "logs an error" do
90
- out = StringIO.new
91
- logger = Logger.new(out)
92
- keys_whitelist = described_class.new(logger, patterns)
93
- keys_whitelist.call(notice)
94
-
95
- expect(out.string).to(
96
- match(/ERROR.+KeysWhitelist is invalid.+patterns: \[#<Proc:.+>\]/)
85
+ expect(Airbrake::Loggable.instance).to receive(:error).with(
86
+ /KeysWhitelist is invalid.+patterns: \[#<Proc:.+>\]/
97
87
  )
88
+ keys_whitelist = described_class.new(patterns)
89
+ keys_whitelist.call(notice)
98
90
  end
99
91
 
100
92
  include_examples(
@@ -120,14 +112,11 @@ RSpec.describe Airbrake::Filters::KeysWhitelist do
120
112
  )
121
113
 
122
114
  it "logs an error" do
123
- out = StringIO.new
124
- logger = Logger.new(out)
125
- keys_whitelist = described_class.new(logger, patterns)
126
- keys_whitelist.call(notice)
127
-
128
- expect(out.string).to(
129
- match(/ERROR.+KeysWhitelist is invalid.+patterns: \[#<Object:.+>\]/)
115
+ expect(Airbrake::Loggable.instance).to receive(:error).with(
116
+ /KeysWhitelist is invalid.+patterns: \[#<Object:.+>\]/
130
117
  )
118
+ keys_whitelist = described_class.new(patterns)
119
+ keys_whitelist.call(notice)
131
120
  end
132
121
  end
133
122
 
@@ -2,10 +2,7 @@ RSpec.describe Airbrake::Filters::RootDirectoryFilter do
2
2
  subject { described_class.new(root_directory) }
3
3
 
4
4
  let(:root_directory) { '/var/www/project' }
5
-
6
- let(:notice) do
7
- Airbrake::Notice.new(Airbrake::Config.new, AirbrakeTestError.new)
8
- end
5
+ let(:notice) { Airbrake::Notice.new(AirbrakeTestError.new) }
9
6
 
10
7
  it "replaces root directory in the backtrace with a label" do
11
8
  # rubocop:disable Metrics/LineLength
@@ -1,13 +1,13 @@
1
1
  RSpec.describe Airbrake::Filters::SystemExitFilter do
2
2
  it "marks SystemExit exceptions as ignored" do
3
- notice = Airbrake::Notice.new(Airbrake::Config.new, SystemExit.new)
3
+ notice = Airbrake::Notice.new(SystemExit.new)
4
4
  expect { subject.call(notice) }.to(
5
5
  change { notice.ignored? }.from(false).to(true)
6
6
  )
7
7
  end
8
8
 
9
9
  it "doesn't mark non SystemExit exceptions as ignored" do
10
- notice = Airbrake::Notice.new(Airbrake::Config.new, AirbrakeTestError.new)
10
+ notice = Airbrake::Notice.new(AirbrakeTestError.new)
11
11
  expect(notice).not_to be_ignored
12
12
  expect { subject.call(notice) }.not_to(change { notice.ignored? })
13
13
  end
@@ -1,7 +1,5 @@
1
1
  RSpec.describe Airbrake::Filters::ThreadFilter do
2
- let(:notice) do
3
- Airbrake::Notice.new(Airbrake::Config.new, AirbrakeTestError.new)
4
- end
2
+ let(:notice) { Airbrake::Notice.new(AirbrakeTestError.new) }
5
3
 
6
4
  def new_thread
7
5
  Thread.new do
@@ -1,6 +1,4 @@
1
1
  RSpec.describe Airbrake::NestedException do
2
- let(:config) { Airbrake::Config.new }
3
-
4
2
  describe "#as_json" do
5
3
  context "given exceptions with backtraces" do
6
4
  it "unwinds nested exceptions" do
@@ -11,7 +9,7 @@ RSpec.describe Airbrake::NestedException do
11
9
  Ruby21Error.raise_error('bingo')
12
10
  end
13
11
  rescue Ruby21Error => ex
14
- nested_exception = described_class.new(config, ex)
12
+ nested_exception = described_class.new(ex)
15
13
  exceptions = nested_exception.as_json
16
14
 
17
15
  expect(exceptions.size).to eq(2)
@@ -38,7 +36,7 @@ RSpec.describe Airbrake::NestedException do
38
36
  end
39
37
  end
40
38
  rescue Ruby21Error => ex
41
- nested_exception = described_class.new(config, ex)
39
+ nested_exception = described_class.new(ex)
42
40
  exceptions = nested_exception.as_json
43
41
 
44
42
  expect(exceptions.size).to eq(3)
@@ -62,7 +60,7 @@ RSpec.describe Airbrake::NestedException do
62
60
  end
63
61
  rescue Ruby21Error => ex1
64
62
  ex1.set_backtrace([])
65
- nested_exception = described_class.new(config, ex1)
63
+ nested_exception = described_class.new(ex1)
66
64
  exceptions = nested_exception.as_json
67
65
 
68
66
  expect(exceptions.size).to eq(2)
@@ -1,18 +1,14 @@
1
1
  # rubocop:disable Layout/DotPosition
2
2
  RSpec.describe Airbrake::NoticeNotifier do
3
- let(:user_params) do
4
- {
3
+ before do
4
+ Airbrake::Config.instance = Airbrake::Config.new(
5
5
  project_id: 1,
6
6
  project_key: 'abc',
7
7
  logger: Logger.new('/dev/null'),
8
8
  performance_stats: true
9
- }
9
+ )
10
10
  end
11
11
 
12
- let(:params) { {} }
13
- let(:config) { Airbrake::Config.new(user_params.merge(params)) }
14
- subject { described_class.new(config) }
15
-
16
12
  describe "#new" do
17
13
  describe "default filter addition" do
18
14
  before { allow_any_instance_of(Airbrake::FilterChain).to receive(:add_filter) }
@@ -30,12 +26,12 @@ RSpec.describe Airbrake::NoticeNotifier do
30
26
  end
31
27
 
32
28
  context "when user config has some whitelist keys" do
33
- let(:params) { { whitelist_keys: %w[foo] } }
29
+ before { Airbrake::Config.instance.merge(whitelist_keys: %w[foo]) }
34
30
 
35
31
  it "appends the whitelist filter" do
36
32
  expect_any_instance_of(Airbrake::FilterChain).to receive(:add_filter)
37
33
  .with(instance_of(Airbrake::Filters::KeysWhitelist))
38
- described_class.new(config)
34
+ subject
39
35
  end
40
36
  end
41
37
 
@@ -43,17 +39,17 @@ RSpec.describe Airbrake::NoticeNotifier do
43
39
  it "doesn't append the whitelist filter" do
44
40
  expect_any_instance_of(Airbrake::FilterChain).not_to receive(:add_filter)
45
41
  .with(instance_of(Airbrake::Filters::KeysWhitelist))
46
- described_class.new(config)
42
+ subject
47
43
  end
48
44
  end
49
45
 
50
46
  context "when user config has some blacklist keys" do
51
- let(:params) { { blacklist_keys: %w[bar] } }
47
+ before { Airbrake::Config.instance.merge(blacklist_keys: %w[bar]) }
52
48
 
53
49
  it "appends the blacklist filter" do
54
50
  expect_any_instance_of(Airbrake::FilterChain).to receive(:add_filter)
55
51
  .with(instance_of(Airbrake::Filters::KeysBlacklist))
56
- described_class.new(config)
52
+ subject
57
53
  end
58
54
  end
59
55
 
@@ -61,17 +57,17 @@ RSpec.describe Airbrake::NoticeNotifier do
61
57
  it "doesn't append the blacklist filter" do
62
58
  expect_any_instance_of(Airbrake::FilterChain).not_to receive(:add_filter)
63
59
  .with(instance_of(Airbrake::Filters::KeysBlacklist))
64
- described_class.new(config)
60
+ subject
65
61
  end
66
62
  end
67
63
 
68
64
  context "when user config specifies a root directory" do
69
- let(:params) { { root_directory: '/foo' } }
65
+ before { Airbrake::Config.instance.merge(root_directory: '/foo') }
70
66
 
71
67
  it "appends the root directory filter" do
72
68
  expect_any_instance_of(Airbrake::FilterChain).to receive(:add_filter)
73
69
  .with(instance_of(Airbrake::Filters::RootDirectoryFilter))
74
- described_class.new(config)
70
+ subject
75
71
  end
76
72
  end
77
73
 
@@ -81,7 +77,7 @@ RSpec.describe Airbrake::NoticeNotifier do
81
77
  .and_return(nil)
82
78
  expect_any_instance_of(Airbrake::FilterChain).not_to receive(:add_filter)
83
79
  .with(instance_of(Airbrake::Filters::RootDirectoryFilter))
84
- described_class.new(config)
80
+ subject
85
81
  end
86
82
  end
87
83
  end
@@ -90,8 +86,6 @@ RSpec.describe Airbrake::NoticeNotifier do
90
86
  describe "#notify" do
91
87
  let(:endpoint) { 'https://api.airbrake.io/api/v3/projects/1/notices' }
92
88
 
93
- subject { described_class.new(Airbrake::Config.new(user_params)) }
94
-
95
89
  let(:body) do
96
90
  {
97
91
  'id' => '00054414-b147-6ffa-85d6-1524d83362a6',
@@ -161,7 +155,12 @@ RSpec.describe Airbrake::NoticeNotifier do
161
155
  end
162
156
 
163
157
  context "when the provided environment is ignored" do
164
- let(:user_params) { { environment: 'test', ignore_environments: %w[test] } }
158
+ before do
159
+ Airbrake::Config.instance.merge(
160
+ environment: 'test',
161
+ ignore_environments: %w[test]
162
+ )
163
+ end
165
164
 
166
165
  it "doesn't send an notice" do
167
166
  expect_any_instance_of(Airbrake::AsyncSender).not_to receive(:send)
@@ -241,7 +240,11 @@ RSpec.describe Airbrake::NoticeNotifier do
241
240
  end
242
241
 
243
242
  context "when the provided environment is ignored" do
244
- let(:params) { { environment: 'test', ignore_environments: %w[test] } }
243
+ before do
244
+ Airbrake::Config.instance.merge(
245
+ environment: 'test', ignore_environments: %w[test]
246
+ )
247
+ end
245
248
 
246
249
  it "doesn't send an notice" do
247
250
  expect_any_instance_of(Airbrake::SyncSender).not_to receive(:send)