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.
- checksums.yaml +4 -4
- data/lib/airbrake-ruby/async_sender.rb +3 -1
- data/lib/airbrake-ruby/config.rb +3 -3
- data/lib/airbrake-ruby/context.rb +51 -0
- data/lib/airbrake-ruby/filter_chain.rb +2 -0
- data/lib/airbrake-ruby/filters/context_filter.rb +4 -5
- data/lib/airbrake-ruby/filters/exception_attributes_filter.rb +1 -1
- data/lib/airbrake-ruby/filters/git_last_checkout_filter.rb +2 -2
- data/lib/airbrake-ruby/filters/git_repository_filter.rb +1 -1
- data/lib/airbrake-ruby/filters/git_revision_filter.rb +1 -1
- data/lib/airbrake-ruby/filters/keys_filter.rb +2 -2
- data/lib/airbrake-ruby/filters/sql_filter.rb +8 -8
- data/lib/airbrake-ruby/filters/thread_filter.rb +1 -1
- data/lib/airbrake-ruby/ignorable.rb +0 -2
- data/lib/airbrake-ruby/monotonic_time.rb +1 -1
- data/lib/airbrake-ruby/notice_notifier.rb +3 -4
- data/lib/airbrake-ruby/performance_notifier.rb +39 -40
- data/lib/airbrake-ruby/remote_settings/settings_data.rb +1 -1
- data/lib/airbrake-ruby/remote_settings.rb +26 -3
- data/lib/airbrake-ruby/stat.rb +1 -1
- data/lib/airbrake-ruby/tdigest.rb +10 -9
- data/lib/airbrake-ruby/thread_pool.rb +8 -6
- data/lib/airbrake-ruby/time_truncate.rb +2 -2
- data/lib/airbrake-ruby/timed_trace.rb +1 -3
- data/lib/airbrake-ruby/version.rb +1 -1
- data/lib/airbrake-ruby.rb +24 -23
- data/spec/airbrake_spec.rb +139 -76
- data/spec/async_sender_spec.rb +10 -8
- data/spec/backtrace_spec.rb +13 -10
- data/spec/benchmark_spec.rb +5 -3
- data/spec/code_hunk_spec.rb +24 -15
- data/spec/config/processor_spec.rb +12 -4
- data/spec/config/validator_spec.rb +5 -2
- data/spec/config_spec.rb +28 -20
- data/spec/context_spec.rb +54 -0
- data/spec/deploy_notifier_spec.rb +6 -4
- data/spec/file_cache_spec.rb +1 -0
- data/spec/filter_chain_spec.rb +29 -24
- data/spec/filters/context_filter_spec.rb +14 -5
- data/spec/filters/dependency_filter_spec.rb +3 -1
- data/spec/filters/exception_attributes_filter_spec.rb +5 -3
- data/spec/filters/gem_root_filter_spec.rb +5 -2
- data/spec/filters/git_last_checkout_filter_spec.rb +10 -12
- data/spec/filters/git_repository_filter.rb +9 -9
- data/spec/filters/git_revision_filter_spec.rb +20 -20
- data/spec/filters/keys_allowlist_spec.rb +25 -16
- data/spec/filters/keys_blocklist_spec.rb +25 -18
- data/spec/filters/root_directory_filter_spec.rb +3 -3
- data/spec/filters/sql_filter_spec.rb +26 -26
- data/spec/filters/system_exit_filter_spec.rb +4 -2
- data/spec/filters/thread_filter_spec.rb +15 -13
- data/spec/loggable_spec.rb +2 -2
- data/spec/monotonic_time_spec.rb +8 -6
- data/spec/nested_exception_spec.rb +46 -46
- data/spec/notice_notifier/options_spec.rb +23 -13
- data/spec/notice_notifier_spec.rb +52 -47
- data/spec/notice_spec.rb +6 -2
- data/spec/performance_notifier_spec.rb +69 -62
- data/spec/promise_spec.rb +38 -32
- data/spec/remote_settings/callback_spec.rb +27 -8
- data/spec/remote_settings/settings_data_spec.rb +4 -4
- data/spec/remote_settings_spec.rb +23 -9
- data/spec/response_spec.rb +34 -12
- data/spec/stashable_spec.rb +5 -5
- data/spec/stat_spec.rb +7 -5
- data/spec/sync_sender_spec.rb +49 -16
- data/spec/tdigest_spec.rb +60 -55
- data/spec/thread_pool_spec.rb +65 -56
- data/spec/time_truncate_spec.rb +23 -6
- data/spec/timed_trace_spec.rb +32 -30
- data/spec/truncator_spec.rb +72 -43
- metadata +54 -50
@@ -20,14 +20,14 @@ RSpec.describe Airbrake::Filters::SqlFilter do
|
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
23
|
-
|
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:
|
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:
|
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:
|
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:
|
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:
|
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:
|
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:
|
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:
|
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:
|
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:
|
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:
|
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:
|
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:
|
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:
|
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:
|
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:
|
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:
|
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:
|
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:
|
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:
|
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:
|
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:
|
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:
|
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:
|
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:
|
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 {
|
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 {
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
275
|
+
thread_filter.call(notice)
|
274
276
|
end
|
275
277
|
|
276
278
|
fiber_variables = notice[:params][:thread][:fiber_variables]
|
data/spec/loggable_spec.rb
CHANGED
@@ -6,12 +6,12 @@ RSpec.describe Airbrake::Loggable do
|
|
6
6
|
end
|
7
7
|
|
8
8
|
describe "#logger" do
|
9
|
-
|
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(
|
14
|
+
expect(class_with_logger.logger.level).to eq(Logger::WARN)
|
15
15
|
end
|
16
16
|
end
|
17
17
|
end
|
data/spec/monotonic_time_spec.rb
CHANGED
@@ -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(
|
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 =
|
9
|
-
expect(
|
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(
|
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 =
|
20
|
-
expect(
|
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
|
-
|
7
|
-
|
8
|
-
|
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
|
-
|
27
|
-
rescue
|
29
|
+
Ruby21Error.raise_error('bongo')
|
30
|
+
rescue Ruby21Error
|
28
31
|
begin
|
29
|
-
Ruby21Error.raise_error('
|
32
|
+
Ruby21Error.raise_error('bango')
|
30
33
|
rescue Ruby21Error
|
31
|
-
|
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
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
211
|
-
|
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 =
|
259
|
+
notice = notice_notifier.build_notice(ex)
|
250
260
|
notice[:context][:headers] = 'banana'
|
251
|
-
|
261
|
+
notice_notifier.notify_sync(notice)
|
252
262
|
|
253
263
|
expect(a_request(:post, endpoint)).to have_been_made
|
254
264
|
end
|