airbrake-ruby 5.2.0-java → 6.0.2-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 (72) hide show
  1. checksums.yaml +4 -4
  2. data/lib/airbrake-ruby/async_sender.rb +3 -1
  3. data/lib/airbrake-ruby/config.rb +3 -3
  4. data/lib/airbrake-ruby/context.rb +51 -0
  5. data/lib/airbrake-ruby/filter_chain.rb +2 -0
  6. data/lib/airbrake-ruby/filters/context_filter.rb +4 -5
  7. data/lib/airbrake-ruby/filters/exception_attributes_filter.rb +1 -1
  8. data/lib/airbrake-ruby/filters/git_last_checkout_filter.rb +2 -2
  9. data/lib/airbrake-ruby/filters/git_repository_filter.rb +1 -1
  10. data/lib/airbrake-ruby/filters/git_revision_filter.rb +1 -1
  11. data/lib/airbrake-ruby/filters/keys_filter.rb +2 -2
  12. data/lib/airbrake-ruby/filters/sql_filter.rb +8 -8
  13. data/lib/airbrake-ruby/filters/thread_filter.rb +1 -1
  14. data/lib/airbrake-ruby/ignorable.rb +0 -2
  15. data/lib/airbrake-ruby/monotonic_time.rb +1 -1
  16. data/lib/airbrake-ruby/notice_notifier.rb +3 -4
  17. data/lib/airbrake-ruby/performance_notifier.rb +39 -40
  18. data/lib/airbrake-ruby/remote_settings/settings_data.rb +1 -1
  19. data/lib/airbrake-ruby/remote_settings.rb +26 -3
  20. data/lib/airbrake-ruby/stat.rb +1 -1
  21. data/lib/airbrake-ruby/tdigest.rb +10 -9
  22. data/lib/airbrake-ruby/thread_pool.rb +8 -6
  23. data/lib/airbrake-ruby/time_truncate.rb +2 -2
  24. data/lib/airbrake-ruby/timed_trace.rb +1 -3
  25. data/lib/airbrake-ruby/version.rb +1 -1
  26. data/lib/airbrake-ruby.rb +24 -23
  27. data/spec/airbrake_spec.rb +139 -76
  28. data/spec/async_sender_spec.rb +10 -8
  29. data/spec/backtrace_spec.rb +13 -10
  30. data/spec/benchmark_spec.rb +5 -3
  31. data/spec/code_hunk_spec.rb +24 -15
  32. data/spec/config/processor_spec.rb +12 -4
  33. data/spec/config/validator_spec.rb +5 -2
  34. data/spec/config_spec.rb +28 -20
  35. data/spec/context_spec.rb +54 -0
  36. data/spec/deploy_notifier_spec.rb +6 -4
  37. data/spec/file_cache_spec.rb +1 -0
  38. data/spec/filter_chain_spec.rb +29 -24
  39. data/spec/filters/context_filter_spec.rb +14 -5
  40. data/spec/filters/dependency_filter_spec.rb +3 -1
  41. data/spec/filters/exception_attributes_filter_spec.rb +5 -3
  42. data/spec/filters/gem_root_filter_spec.rb +5 -2
  43. data/spec/filters/git_last_checkout_filter_spec.rb +10 -12
  44. data/spec/filters/git_repository_filter.rb +9 -9
  45. data/spec/filters/git_revision_filter_spec.rb +20 -20
  46. data/spec/filters/keys_allowlist_spec.rb +25 -16
  47. data/spec/filters/keys_blocklist_spec.rb +25 -18
  48. data/spec/filters/root_directory_filter_spec.rb +3 -3
  49. data/spec/filters/sql_filter_spec.rb +26 -26
  50. data/spec/filters/system_exit_filter_spec.rb +4 -2
  51. data/spec/filters/thread_filter_spec.rb +15 -13
  52. data/spec/loggable_spec.rb +2 -2
  53. data/spec/monotonic_time_spec.rb +8 -6
  54. data/spec/nested_exception_spec.rb +46 -46
  55. data/spec/notice_notifier/options_spec.rb +23 -13
  56. data/spec/notice_notifier_spec.rb +52 -47
  57. data/spec/notice_spec.rb +6 -2
  58. data/spec/performance_notifier_spec.rb +69 -62
  59. data/spec/promise_spec.rb +38 -32
  60. data/spec/remote_settings/callback_spec.rb +27 -8
  61. data/spec/remote_settings/settings_data_spec.rb +4 -4
  62. data/spec/remote_settings_spec.rb +23 -9
  63. data/spec/response_spec.rb +34 -12
  64. data/spec/stashable_spec.rb +5 -5
  65. data/spec/stat_spec.rb +7 -5
  66. data/spec/sync_sender_spec.rb +49 -16
  67. data/spec/tdigest_spec.rb +60 -55
  68. data/spec/thread_pool_spec.rb +65 -56
  69. data/spec/time_truncate_spec.rb +23 -6
  70. data/spec/timed_trace_spec.rb +32 -30
  71. data/spec/truncator_spec.rb +72 -43
  72. metadata +54 -50
@@ -20,14 +20,14 @@ RSpec.describe Airbrake::Filters::SqlFilter do
20
20
  end
21
21
  end
22
22
 
23
- ALL_DIALECTS = %i[mysql postgres sqlite cassandra oracle].freeze
23
+ all_dialects = %i[mysql postgres sqlite cassandra oracle].freeze
24
24
 
25
25
  # rubocop:disable Layout/LineLength
26
26
  [
27
27
  {
28
28
  input: 'SELECT * FROM things;',
29
29
  output: 'SELECT * FROM things;',
30
- dialects: ALL_DIALECTS,
30
+ dialects: all_dialects,
31
31
  }, {
32
32
  input: "SELECT `t001`.`c2` FROM `t001` WHERE `t001`.`c2` = 'value' AND c3=\"othervalue\" LIMIT ?",
33
33
  output: "SELECT `t001`.`c2` FROM `t001` WHERE `t001`.`c2` = ? AND c3=? LIMIT ?",
@@ -39,7 +39,7 @@ RSpec.describe Airbrake::Filters::SqlFilter do
39
39
  }, {
40
40
  input: "SELECT * FROM t WHERE foo='bar/*' AND baz='whatever */qux'",
41
41
  output: "SELECT * FROM t WHERE foo=? AND baz=?",
42
- dialects: ALL_DIALECTS,
42
+ dialects: all_dialects,
43
43
  }, {
44
44
  input: "SELECT \"t001\".\"c2\" FROM \"t001\" WHERE \"t001\".\"c2\" = 'value' AND c3=1234 LIMIT 1",
45
45
  output: "SELECT \"t001\".\"c2\" FROM \"t001\" WHERE \"t001\".\"c2\" = ? AND c3=? LIMIT ?",
@@ -51,19 +51,19 @@ RSpec.describe Airbrake::Filters::SqlFilter do
51
51
  }, {
52
52
  input: "SELECT * FROM t WHERE foo='bar--' AND\n baz='qux--'",
53
53
  output: "SELECT * FROM t WHERE foo=? AND\n baz=?",
54
- dialects: ALL_DIALECTS,
54
+ dialects: all_dialects,
55
55
  }, {
56
56
  input: "SELECT * FROM foo WHERE bar='baz' /* Hide Me */",
57
57
  output: "SELECT * FROM foo WHERE bar=? ?",
58
- dialects: ALL_DIALECTS,
58
+ dialects: all_dialects,
59
59
  }, {
60
60
  input: "SELECT * FROM foobar WHERE password='hunter2'\n-- No peeking!",
61
61
  output: "SELECT * FROM foobar WHERE password=?\n?",
62
- dialects: ALL_DIALECTS,
62
+ dialects: all_dialects,
63
63
  }, {
64
64
  input: "SELECT foo, bar FROM baz WHERE password='hunter2' # Secret",
65
65
  output: "SELECT foo, bar FROM baz WHERE password=? ?",
66
- dialects: ALL_DIALECTS,
66
+ dialects: all_dialects,
67
67
  }, {
68
68
  input: "SELECT \"col1\", \"col2\" from \"table\" WHERE \"col3\"=E'foo\\'bar\\\\baz' AND country=e'foo\\'bar\\\\baz'",
69
69
  output: "SELECT \"col1\", \"col2\" from \"table\" WHERE \"col3\"=E?",
@@ -79,11 +79,11 @@ RSpec.describe Airbrake::Filters::SqlFilter do
79
79
  }, {
80
80
  input: "SELECT c11.col1, c22.col2 FROM table c11, table c22 WHERE value='nothing'",
81
81
  output: "SELECT c11.col1, c22.col2 FROM table c11, table c22 WHERE value=?",
82
- dialects: ALL_DIALECTS,
82
+ dialects: all_dialects,
83
83
  }, {
84
84
  input: "INSERT INTO X VALUES(1, 23456, 123.456, 99+100)",
85
85
  output: "INSERT INTO X VALUES(?)",
86
- dialects: ALL_DIALECTS,
86
+ dialects: all_dialects,
87
87
  }, {
88
88
  input: "SELECT * FROM table WHERE name=\"foo\" AND value=\"don't\"",
89
89
  output: "SELECT * FROM table WHERE name=? AND value=?",
@@ -91,19 +91,19 @@ RSpec.describe Airbrake::Filters::SqlFilter do
91
91
  }, {
92
92
  input: "SELECT * FROM table WHERE name='foo' AND value = 'bar'",
93
93
  output: "SELECT * FROM table WHERE name=? AND value = ?",
94
- dialects: ALL_DIALECTS,
94
+ dialects: all_dialects,
95
95
  }, {
96
96
  input: "SELECT * FROM table WHERE col='foo\\''bar'",
97
97
  output: "SELECT * FROM table WHERE col=?",
98
- dialects: ALL_DIALECTS,
98
+ dialects: all_dialects,
99
99
  }, {
100
100
  input: "SELECT * FROM table WHERE col1='foo\"bar' AND col2='what\"ever'",
101
101
  output: "SELECT * FROM table WHERE col1=? AND col2=?",
102
- dialects: ALL_DIALECTS,
102
+ dialects: all_dialects,
103
103
  }, {
104
104
  input: "select * from accounts where accounts.name != 'dude\n newline' order by accounts.name",
105
105
  output: "select * from accounts where accounts.name != ? order by accounts.name",
106
- dialects: ALL_DIALECTS,
106
+ dialects: all_dialects,
107
107
  }, {
108
108
  input: "SELECT * FROM table WHERE col1=\"don't\" AND col2=\"won't\"",
109
109
  output: "SELECT * FROM table WHERE col1=? AND col2=?",
@@ -115,7 +115,7 @@ RSpec.describe Airbrake::Filters::SqlFilter do
115
115
  }, {
116
116
  input: "SELECT * FROM table WHERE name='foo\\' AND color='blue'",
117
117
  output: "SELECT * FROM table WHERE name=?",
118
- dialects: ALL_DIALECTS,
118
+ dialects: all_dialects,
119
119
  }, {
120
120
  input: "SELECT * FROM table WHERE foo=\"this string ends with a backslash\\\\\"",
121
121
  output: "SELECT * FROM table WHERE foo=?",
@@ -123,36 +123,36 @@ RSpec.describe Airbrake::Filters::SqlFilter do
123
123
  }, {
124
124
  input: "SELECT * FROM table WHERE foo='this string ends with a backslash\\\\'",
125
125
  output: "SELECT * FROM table WHERE foo=?",
126
- dialects: ALL_DIALECTS,
126
+ dialects: all_dialects,
127
127
  }, {
128
128
  # TODO: fix this example.
129
129
  input: "SELECT * FROM table WHERE name='foo\'' AND color='blue'",
130
130
  output: "Error: Airbrake::Query was not filtered",
131
- dialects: ALL_DIALECTS,
131
+ dialects: all_dialects,
132
132
  }, {
133
133
  input: "INSERT INTO X values('', 'a''b c',0, 1 , 'd''e f''s h')",
134
134
  output: "INSERT INTO X values(?)",
135
- dialects: ALL_DIALECTS,
135
+ dialects: all_dialects,
136
136
  }, {
137
137
  input: "SELECT * FROM t WHERE -- '\n bar='baz' -- '",
138
138
  output: "SELECT * FROM t WHERE ?\n bar=? ?",
139
- dialects: ALL_DIALECTS,
139
+ dialects: all_dialects,
140
140
  }, {
141
141
  input: "SELECT * FROM t WHERE /* ' */\n bar='baz' -- '",
142
142
  output: "SELECT * FROM t WHERE ?\n bar=? ?",
143
- dialects: ALL_DIALECTS,
143
+ dialects: all_dialects,
144
144
  }, {
145
145
  input: "SELECT * FROM t WHERE -- '\n /* ' */ c2='xxx' /* ' */\n c='x\n xx' -- '",
146
146
  output: "SELECT * FROM t WHERE ?\n ? c2=? ?\n c=? ?",
147
- dialects: ALL_DIALECTS,
147
+ dialects: all_dialects,
148
148
  }, {
149
149
  input: "SELECT * FROM t WHERE -- '\n c='x\n xx' -- '",
150
150
  output: "SELECT * FROM t WHERE ?\n c=? ?",
151
- dialects: ALL_DIALECTS,
151
+ dialects: all_dialects,
152
152
  }, {
153
153
  input: "SELECT * FROM foo WHERE col='value1' AND /* don't */ col2='value1' /* won't */",
154
154
  output: "SELECT * FROM foo WHERE col=? AND ? col2=? ?",
155
- dialects: ALL_DIALECTS,
155
+ dialects: all_dialects,
156
156
  }, {
157
157
  input: "SELECT * FROM table WHERE foo='bar' AND baz=\"nothing to see here'",
158
158
  output: "Error: Airbrake::Query was not filtered",
@@ -160,7 +160,7 @@ RSpec.describe Airbrake::Filters::SqlFilter do
160
160
  }, {
161
161
  input: "SELECT * FROM table WHERE foo='bar' AND baz='nothing to see here",
162
162
  output: "Error: Airbrake::Query was not filtered",
163
- dialects: ALL_DIALECTS,
163
+ dialects: all_dialects,
164
164
  }, {
165
165
  input: "SELECT * FROM \"foo\" WHERE \"foo\" = $a$dollar quotes can be $b$nested$b$$a$ and bar = 'baz'",
166
166
  output: "SELECT * FROM \"foo\" WHERE \"foo\" = ? and bar = ?",
@@ -172,11 +172,11 @@ RSpec.describe Airbrake::Filters::SqlFilter do
172
172
  }, {
173
173
  input: "select * from foo where bar = 'some\\tthing' and baz = 10",
174
174
  output: "select * from foo where bar = ? and baz = ?",
175
- dialects: ALL_DIALECTS,
175
+ dialects: all_dialects,
176
176
  }, {
177
177
  input: "select * from users where user = 'user1\\' password = 'hunter 2' -- ->don't count this quote",
178
178
  output: "select * from users where user = ?",
179
- dialects: ALL_DIALECTS,
179
+ dialects: all_dialects,
180
180
  }, {
181
181
  input: "select * from foo where bar=q'[baz's]' and x=5",
182
182
  output: "select * from foo where bar=? and x=?",
@@ -204,7 +204,7 @@ RSpec.describe Airbrake::Filters::SqlFilter do
204
204
  }, {
205
205
  input: "select * from foo where bar=1.234e-5 and x=5",
206
206
  output: "select * from foo where bar=? and x=?",
207
- dialects: ALL_DIALECTS,
207
+ dialects: all_dialects,
208
208
  }, {
209
209
  input: "select * from foo where bar=01234567-89ab-cdef-0123-456789abcdef and x=5",
210
210
  output: "select * from foo where bar=? and x=?",
@@ -1,7 +1,9 @@
1
1
  RSpec.describe Airbrake::Filters::SystemExitFilter do
2
+ subject(:system_exit_filter) { described_class.new }
3
+
2
4
  it "marks SystemExit exceptions as ignored" do
3
5
  notice = Airbrake::Notice.new(SystemExit.new)
4
- expect { subject.call(notice) }.to(
6
+ expect { system_exit_filter.call(notice) }.to(
5
7
  change { notice.ignored? }.from(false).to(true),
6
8
  )
7
9
  end
@@ -9,6 +11,6 @@ RSpec.describe Airbrake::Filters::SystemExitFilter do
9
11
  it "doesn't mark non SystemExit exceptions as ignored" do
10
12
  notice = Airbrake::Notice.new(AirbrakeTestError.new)
11
13
  expect(notice).not_to be_ignored
12
- expect { subject.call(notice) }.not_to(change { notice.ignored? })
14
+ expect { system_exit_filter.call(notice) }.not_to(change { notice.ignored? })
13
15
  end
14
16
  end
@@ -1,4 +1,6 @@
1
1
  RSpec.describe Airbrake::Filters::ThreadFilter do
2
+ subject(:thread_filter) { described_class.new }
3
+
2
4
  let(:notice) { Airbrake::Notice.new(AirbrakeTestError.new) }
3
5
 
4
6
  def new_thread
@@ -17,7 +19,7 @@ RSpec.describe Airbrake::Filters::ThreadFilter do
17
19
  it "attaches the thread variable" do
18
20
  new_thread do |th|
19
21
  th.thread_variable_set(:bingo, var)
20
- subject.call(notice)
22
+ thread_filter.call(notice)
21
23
  end
22
24
 
23
25
  expect(notice[:params][:thread][:thread_variables][:bingo]).to eq(var)
@@ -60,7 +62,7 @@ RSpec.describe Airbrake::Filters::ThreadFilter do
60
62
  it "converts it to a String and attaches" do
61
63
  new_thread do |th|
62
64
  th.thread_variable_set(:bingo, Object.new)
63
- subject.call(notice)
65
+ thread_filter.call(notice)
64
66
  end
65
67
 
66
68
  vars = notice[:params][:thread][:thread_variables]
@@ -90,7 +92,7 @@ RSpec.describe Airbrake::Filters::ThreadFilter do
90
92
  it "converts objects to a safe objects" do
91
93
  new_thread do |th|
92
94
  th.thread_variable_set(:bingo, var)
93
- subject.call(notice)
95
+ thread_filter.call(notice)
94
96
  end
95
97
 
96
98
  vars = notice[:params][:thread][:thread_variables]
@@ -121,7 +123,7 @@ RSpec.describe Airbrake::Filters::ThreadFilter do
121
123
 
122
124
  new_thread do |th|
123
125
  th.thread_variable_set(var, :bingo)
124
- subject.call(notice)
126
+ thread_filter.call(notice)
125
127
  end
126
128
 
127
129
  thread_variables = notice[:params][:thread][:thread_variables]
@@ -134,7 +136,7 @@ RSpec.describe Airbrake::Filters::ThreadFilter do
134
136
  it "attaches the fiber variable" do
135
137
  new_thread do |th|
136
138
  th[:bingo] = var
137
- subject.call(notice)
139
+ thread_filter.call(notice)
138
140
  end
139
141
 
140
142
  expect(notice[:params][:thread][:fiber_variables][:bingo]).to eq(var)
@@ -177,7 +179,7 @@ RSpec.describe Airbrake::Filters::ThreadFilter do
177
179
  it "converts it to a String and attaches" do
178
180
  new_thread do |th|
179
181
  th[:bingo] = Object.new
180
- subject.call(notice)
182
+ thread_filter.call(notice)
181
183
  end
182
184
 
183
185
  vars = notice[:params][:thread][:fiber_variables]
@@ -207,7 +209,7 @@ RSpec.describe Airbrake::Filters::ThreadFilter do
207
209
  it "converts objects to a safe objects" do
208
210
  new_thread do |th|
209
211
  th[:bingo] = var
210
- subject.call(notice)
212
+ thread_filter.call(notice)
211
213
  end
212
214
 
213
215
  vars = notice[:params][:thread][:fiber_variables]
@@ -237,31 +239,31 @@ RSpec.describe Airbrake::Filters::ThreadFilter do
237
239
  it "appends name" do
238
240
  new_thread do |th|
239
241
  th.name = 'bingo'
240
- subject.call(notice)
242
+ thread_filter.call(notice)
241
243
  end
242
244
 
243
245
  expect(notice[:params][:thread][:name]).to eq('bingo')
244
246
  end
245
247
 
246
248
  it "appends thread inspect (self)" do
247
- subject.call(notice)
249
+ thread_filter.call(notice)
248
250
  expect(notice[:params][:thread][:self]).to match(/\A#<Thread:.+>\z/)
249
251
  end
250
252
 
251
253
  it "appends thread group" do
252
- subject.call(notice)
254
+ thread_filter.call(notice)
253
255
  expect(notice[:params][:thread][:group][0]).to match(/\A#<Thread:.+>\z/)
254
256
  end
255
257
 
256
258
  it "appends priority" do
257
- subject.call(notice)
259
+ thread_filter.call(notice)
258
260
  expect(notice[:params][:thread][:priority]).to eq(0)
259
261
  end
260
262
 
261
263
  it "appends safe_level", skip: (
262
264
  "Not supported on this version of Ruby." unless Airbrake::HAS_SAFE_LEVEL
263
265
  ) do
264
- subject.call(notice)
266
+ thread_filter.call(notice)
265
267
  expect(notice[:params][:thread][:safe_level]).to eq(0)
266
268
  end
267
269
 
@@ -270,7 +272,7 @@ RSpec.describe Airbrake::Filters::ThreadFilter do
270
272
 
271
273
  new_thread do |th|
272
274
  th[key] = :bingo
273
- subject.call(notice)
275
+ thread_filter.call(notice)
274
276
  end
275
277
 
276
278
  fiber_variables = notice[:params][:thread][:fiber_variables]
@@ -6,12 +6,12 @@ RSpec.describe Airbrake::Loggable do
6
6
  end
7
7
 
8
8
  describe "#logger" do
9
- let(:subject) do
9
+ subject(:class_with_logger) do
10
10
  Class.new { include Airbrake::Loggable }.new
11
11
  end
12
12
 
13
13
  it "returns a logger that has Logger::WARN severity" do
14
- expect(subject.logger.level).to eq(Logger::WARN)
14
+ expect(class_with_logger.logger.level).to eq(Logger::WARN)
15
15
  end
16
16
  end
17
17
  end
@@ -1,23 +1,25 @@
1
1
  RSpec.describe Airbrake::MonotonicTime do
2
+ subject(:monotonic_time) { described_class }
3
+
2
4
  describe ".time_in_ms" do
3
5
  it "returns monotonic time in milliseconds" do
4
- expect(subject.time_in_ms).to be_a(Float)
6
+ expect(monotonic_time.time_in_ms).to be_a(Float)
5
7
  end
6
8
 
7
9
  it "always returns time in the future" do
8
- old_time = subject.time_in_ms
9
- expect(subject.time_in_ms).to be > old_time
10
+ old_time = monotonic_time.time_in_ms
11
+ expect(monotonic_time.time_in_ms).to be > old_time
10
12
  end
11
13
  end
12
14
 
13
15
  describe ".time_in_s" do
14
16
  it "returns monotonic time in seconds" do
15
- expect(subject.time_in_s).to be_a(Float)
17
+ expect(monotonic_time.time_in_s).to be_a(Float)
16
18
  end
17
19
 
18
20
  it "always returns time in the future" do
19
- old_time = subject.time_in_s
20
- expect(subject.time_in_s).to be > old_time
21
+ old_time = monotonic_time.time_in_s
22
+ expect(monotonic_time.time_in_s).to be > old_time
21
23
  end
22
24
  end
23
25
  end
@@ -1,73 +1,73 @@
1
1
  RSpec.describe Airbrake::NestedException do
2
2
  describe "#as_json" do
3
3
  context "given exceptions with backtraces" do
4
+ # rubocop:disable RSpec/MultipleExpectations
4
5
  it "unwinds nested exceptions" do
5
6
  begin
6
- begin
7
- raise AirbrakeTestError
8
- rescue AirbrakeTestError
9
- Ruby21Error.raise_error('bingo')
10
- end
11
- rescue Ruby21Error => ex
12
- nested_exception = described_class.new(ex)
13
- exceptions = nested_exception.as_json
14
-
15
- expect(exceptions.size).to eq(2)
16
- expect(exceptions[0][:message]).to eq('bingo')
17
- expect(exceptions[1][:message]).to eq('App crashed!')
18
- expect(exceptions[0][:backtrace]).not_to be_empty
19
- expect(exceptions[1][:backtrace]).not_to be_empty
7
+ raise AirbrakeTestError
8
+ rescue AirbrakeTestError
9
+ Ruby21Error.raise_error('bingo')
20
10
  end
11
+ rescue Ruby21Error => ex
12
+ nested_exception = described_class.new(ex)
13
+ exceptions = nested_exception.as_json
14
+
15
+ expect(exceptions.size).to eq(2)
16
+ expect(exceptions[0][:message]).to eq('bingo')
17
+ expect(exceptions[1][:message]).to eq('App crashed!')
18
+ expect(exceptions[0][:backtrace]).not_to be_empty
19
+ expect(exceptions[1][:backtrace]).not_to be_empty
21
20
  end
21
+ # rubocop:enable RSpec/MultipleExpectations
22
22
 
23
+ # rubocop:disable RSpec/MultipleExpectations
23
24
  it "unwinds no more than 3 nested exceptions" do
24
25
  begin
26
+ raise AirbrakeTestError
27
+ rescue AirbrakeTestError
25
28
  begin
26
- raise AirbrakeTestError
27
- rescue AirbrakeTestError
29
+ Ruby21Error.raise_error('bongo')
30
+ rescue Ruby21Error
28
31
  begin
29
- Ruby21Error.raise_error('bongo')
32
+ Ruby21Error.raise_error('bango')
30
33
  rescue Ruby21Error
31
- begin
32
- Ruby21Error.raise_error('bango')
33
- rescue Ruby21Error
34
- Ruby21Error.raise_error('bingo')
35
- end
34
+ Ruby21Error.raise_error('bingo')
36
35
  end
37
36
  end
38
- rescue Ruby21Error => ex
39
- nested_exception = described_class.new(ex)
40
- exceptions = nested_exception.as_json
41
-
42
- expect(exceptions.size).to eq(3)
43
- expect(exceptions[0][:message]).to eq('bingo')
44
- expect(exceptions[1][:message]).to eq('bango')
45
- expect(exceptions[2][:message]).to eq('bongo')
46
- expect(exceptions[0][:backtrace]).not_to be_empty
47
- expect(exceptions[1][:backtrace]).not_to be_empty
48
37
  end
38
+ rescue Ruby21Error => ex
39
+ nested_exception = described_class.new(ex)
40
+ exceptions = nested_exception.as_json
41
+
42
+ expect(exceptions.size).to eq(3)
43
+ expect(exceptions[0][:message]).to eq('bingo')
44
+ expect(exceptions[1][:message]).to eq('bango')
45
+ expect(exceptions[2][:message]).to eq('bongo')
46
+ expect(exceptions[0][:backtrace]).not_to be_empty
47
+ expect(exceptions[1][:backtrace]).not_to be_empty
49
48
  end
49
+ # rubocop:enable RSpec/MultipleExpectations
50
50
  end
51
51
 
52
52
  context "given exceptions without backtraces" do
53
+ # rubocop:disable RSpec/MultipleExpectations
53
54
  it "sets backtrace to nil" do
54
55
  begin
55
- begin
56
- raise AirbrakeTestError
57
- rescue AirbrakeTestError => ex2
58
- ex2.set_backtrace([])
59
- Ruby21Error.raise_error('bingo')
60
- end
61
- rescue Ruby21Error => ex1
62
- ex1.set_backtrace([])
63
- nested_exception = described_class.new(ex1)
64
- exceptions = nested_exception.as_json
65
-
66
- expect(exceptions.size).to eq(2)
67
- expect(exceptions[0][:backtrace]).to be_empty
68
- expect(exceptions[1][:backtrace]).to be_empty
56
+ raise AirbrakeTestError
57
+ rescue AirbrakeTestError => ex2
58
+ ex2.set_backtrace([])
59
+ Ruby21Error.raise_error('bingo')
69
60
  end
61
+ rescue Ruby21Error => ex1
62
+ ex1.set_backtrace([])
63
+ nested_exception = described_class.new(ex1)
64
+ exceptions = nested_exception.as_json
65
+
66
+ expect(exceptions.size).to eq(2)
67
+ expect(exceptions[0][:backtrace]).to be_empty
68
+ expect(exceptions[1][:backtrace]).to be_empty
70
69
  end
70
+ # rubocop:enable RSpec/MultipleExpectations
71
71
  end
72
72
  end
73
73
  end
@@ -1,4 +1,6 @@
1
1
  RSpec.describe Airbrake::NoticeNotifier do
2
+ subject(:notice_notifier) { described_class.new }
3
+
2
4
  let(:project_id) { 105138 }
3
5
  let(:project_key) { 'fd04e13d806a90f96614ad8e529b2822' }
4
6
  let(:localhost) { 'http://localhost:8080' }
@@ -27,7 +29,7 @@ RSpec.describe Airbrake::NoticeNotifier do
27
29
 
28
30
  example(title) do
29
31
  stub_request(:post, endpoint).to_return(status: 201, body: '{}')
30
- subject.notify_sync(ex)
32
+ notice_notifier.notify_sync(ex)
31
33
 
32
34
  expect(a_request(:post, endpoint)).to have_been_made.once
33
35
  end
@@ -35,7 +37,7 @@ RSpec.describe Airbrake::NoticeNotifier do
35
37
 
36
38
  path = '/api/v3/projects/105138/notices'
37
39
 
38
- context "given a full host" do
40
+ context "given a full host with port" do
39
41
  include_examples('endpoint', localhost = 'http://localhost:8080',
40
42
  URI.join(localhost, path),
41
43
  "sends notices to the specified host's endpoint")
@@ -63,13 +65,13 @@ RSpec.describe Airbrake::NoticeNotifier do
63
65
 
64
66
  describe ":root_directory" do
65
67
  before do
66
- subject.add_filter(
68
+ notice_notifier.add_filter(
67
69
  Airbrake::Filters::RootDirectoryFilter.new('/home/kyrylo/code'),
68
70
  )
69
71
  end
70
72
 
71
73
  it "filters out frames" do
72
- subject.notify_sync(ex)
74
+ notice_notifier.notify_sync(ex)
73
75
 
74
76
  expect(
75
77
  a_request(:post, endpoint)
@@ -82,7 +84,7 @@ RSpec.describe Airbrake::NoticeNotifier do
82
84
  before { Airbrake::Config.instance.merge(root_directory: dir) }
83
85
 
84
86
  it "being included into the notice's payload" do
85
- subject.notify_sync(ex)
87
+ notice_notifier.notify_sync(ex)
86
88
  expect(
87
89
  a_request(:post, endpoint)
88
90
  .with(body: %r{"rootDirectory":"/bingo/bango"}),
@@ -100,6 +102,7 @@ RSpec.describe Airbrake::NoticeNotifier do
100
102
  end
101
103
  end
102
104
 
105
+ # rubocop:disable RSpec/MultipleMemoizedHelpers
103
106
  describe ":proxy" do
104
107
  let(:proxy) do
105
108
  WEBrick::HTTPServer.new(
@@ -142,7 +145,7 @@ RSpec.describe Airbrake::NoticeNotifier do
142
145
  "safe to run this test on 2.6+ once we upgrade to Webmock 3.5+",
143
146
  )
144
147
  end
145
- subject.notify_sync(ex)
148
+ notice_notifier.notify_sync(ex)
146
149
 
147
150
  proxied_request = requests.pop(true)
148
151
 
@@ -155,13 +158,14 @@ RSpec.describe Airbrake::NoticeNotifier do
155
158
  # rubocop:enable Layout/LineLength
156
159
  end
157
160
  end
161
+ # rubocop:enable RSpec/MultipleMemoizedHelpers
158
162
 
159
163
  describe ":environment" do
160
164
  context "when present" do
161
165
  before { Airbrake::Config.instance.merge(environment: :production) }
162
166
 
163
167
  it "being included into the notice's payload" do
164
- subject.notify_sync(ex)
168
+ notice_notifier.notify_sync(ex)
165
169
  expect(
166
170
  a_request(:post, endpoint)
167
171
  .with(body: /"context":{.*"environment":"production".*}/),
@@ -175,7 +179,7 @@ RSpec.describe Airbrake::NoticeNotifier do
175
179
  before { Airbrake::Config.instance.merge(params) }
176
180
 
177
181
  it "sends a notice" do
178
- subject.notify_sync(ex)
182
+ notice_notifier.notify_sync(ex)
179
183
  expect(a_request(:post, endpoint)).to have_been_made
180
184
  end
181
185
  end
@@ -184,7 +188,7 @@ RSpec.describe Airbrake::NoticeNotifier do
184
188
  before { Airbrake::Config.instance.merge(params) }
185
189
 
186
190
  it "ignores exceptions occurring in envs that were not configured" do
187
- subject.notify_sync(ex)
191
+ notice_notifier.notify_sync(ex)
188
192
  expect(a_request(:post, endpoint)).not_to have_been_made
189
193
  end
190
194
  end
@@ -207,9 +211,15 @@ RSpec.describe Airbrake::NoticeNotifier do
207
211
  include_examples 'ignored notice', params
208
212
 
209
213
  it "returns early and doesn't try to parse the given exception" do
210
- expect(Airbrake::Notice).not_to receive(:new)
211
- expect(subject.notify_sync(ex))
214
+ allow(Airbrake::Notice).to receive(:new)
215
+
216
+ expect(notice_notifier.notify_sync(ex))
212
217
  .to eq('error' => "current environment 'development' is ignored")
218
+
219
+ expect(Airbrake::Notice).not_to have_received(:new)
220
+ end
221
+
222
+ it "doesn't make an HTTP request" do
213
223
  expect(a_request(:post, endpoint)).not_to have_been_made
214
224
  end
215
225
  end
@@ -246,9 +256,9 @@ RSpec.describe Airbrake::NoticeNotifier do
246
256
  end
247
257
 
248
258
  it "sends a notice" do
249
- notice = subject.build_notice(ex)
259
+ notice = notice_notifier.build_notice(ex)
250
260
  notice[:context][:headers] = 'banana'
251
- subject.notify_sync(notice)
261
+ notice_notifier.notify_sync(notice)
252
262
 
253
263
  expect(a_request(:post, endpoint)).to have_been_made
254
264
  end