bugsnag 1.8.6 → 1.8.7
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/.gitignore +2 -1
- data/CHANGELOG.md +7 -0
- data/README.md +11 -5
- data/VERSION +1 -1
- data/bugsnag.gemspec +2 -1
- data/lib/bugsnag/notification.rb +15 -1
- data/lib/bugsnag/tasks/bugsnag.cap +4 -1
- data/lib/bugsnag/tasks/bugsnag.rake +15 -11
- data/spec/helper_spec.rb +30 -30
- data/spec/middleware_spec.rb +37 -39
- data/spec/notification_spec.rb +227 -212
- data/spec/rack_spec.rb +9 -9
- data/spec/spec_helper.rb +4 -2
- metadata +24 -24
data/spec/notification_spec.rb
CHANGED
@@ -16,39 +16,52 @@ class Ruby21Exception < RuntimeError
|
|
16
16
|
end
|
17
17
|
|
18
18
|
describe Bugsnag::Notification do
|
19
|
+
def notify_test_exception
|
20
|
+
Bugsnag.notify(RuntimeError.new("test message"))
|
21
|
+
end
|
22
|
+
|
19
23
|
it "should contain an api_key if one is set" do
|
20
|
-
Bugsnag::Notification.
|
21
|
-
payload[:apiKey].
|
24
|
+
expect(Bugsnag::Notification).to receive(:deliver_exception_payload) do |endpoint, payload|
|
25
|
+
expect(payload[:apiKey]).to eq("c9d60ae4c7e70c4b6c4ebd3e8056d2b8")
|
22
26
|
end
|
23
27
|
|
24
28
|
Bugsnag.notify(BugsnagTestException.new("It crashed"))
|
25
29
|
end
|
26
30
|
|
27
|
-
it "
|
31
|
+
it "does not notify if api_key is not set" do
|
28
32
|
Bugsnag.configuration.api_key = nil
|
29
33
|
|
30
|
-
Bugsnag::Notification.
|
34
|
+
expect(Bugsnag::Notification).not_to receive(:deliver_exception_payload)
|
31
35
|
|
32
36
|
Bugsnag.notify(BugsnagTestException.new("It crashed"))
|
33
37
|
end
|
34
38
|
|
35
|
-
it "
|
39
|
+
it "does not notify if api_key is empty" do
|
36
40
|
Bugsnag.configuration.api_key = ""
|
37
41
|
|
38
|
-
Bugsnag::Notification.
|
42
|
+
expect(Bugsnag::Notification).not_to receive(:deliver_exception_payload)
|
39
43
|
|
40
44
|
Bugsnag.notify(BugsnagTestException.new("It crashed"))
|
41
45
|
end
|
42
46
|
|
43
|
-
it "
|
44
|
-
Bugsnag::Notification.
|
45
|
-
payload[:apiKey].
|
47
|
+
it "lets you override the api_key" do
|
48
|
+
expect(Bugsnag::Notification).to receive(:deliver_exception_payload) do |endpoint, payload|
|
49
|
+
expect(payload[:apiKey]).to eq("9d84383f9be2ca94902e45c756a9979d")
|
46
50
|
end
|
47
51
|
|
48
52
|
Bugsnag.notify(BugsnagTestException.new("It crashed"), :api_key => "9d84383f9be2ca94902e45c756a9979d")
|
49
53
|
end
|
50
54
|
|
51
|
-
it "
|
55
|
+
it "lets you override the groupingHash" do
|
56
|
+
expect(Bugsnag::Notification).to receive(:deliver_exception_payload) do |endpoint, payload|
|
57
|
+
event = get_event_from_payload(payload)
|
58
|
+
expect(event[:groupingHash]).to eq("this is my grouping hash")
|
59
|
+
end
|
60
|
+
|
61
|
+
Bugsnag.notify(BugsnagTestException.new("It crashed"), {:grouping_hash => "this is my grouping hash"})
|
62
|
+
end
|
63
|
+
|
64
|
+
it "uses the env variable apiKey" do
|
52
65
|
ENV["BUGSNAG_API_KEY"] = "c9d60ae4c7e70c4b6c4ebd3e8056d2b9"
|
53
66
|
|
54
67
|
Bugsnag.instance_variable_set(:@configuration, Bugsnag::Configuration.new)
|
@@ -56,46 +69,48 @@ describe Bugsnag::Notification do
|
|
56
69
|
config.release_stage = "production"
|
57
70
|
end
|
58
71
|
|
59
|
-
Bugsnag::Notification.
|
60
|
-
payload[:apiKey].
|
72
|
+
expect(Bugsnag::Notification).to receive(:deliver_exception_payload) do |endpoint, payload|
|
73
|
+
expect(payload[:apiKey]).to eq("c9d60ae4c7e70c4b6c4ebd3e8056d2b9")
|
61
74
|
end
|
62
75
|
|
63
76
|
Bugsnag.notify(BugsnagTestException.new("It crashed"))
|
64
77
|
end
|
65
78
|
|
66
|
-
it "
|
67
|
-
Bugsnag::Notification.
|
79
|
+
it "has the right exception class" do
|
80
|
+
expect(Bugsnag::Notification).to receive(:deliver_exception_payload) do |endpoint, payload|
|
68
81
|
exception = get_exception_from_payload(payload)
|
69
|
-
exception[:errorClass].
|
82
|
+
expect(exception[:errorClass]).to eq("BugsnagTestException")
|
70
83
|
end
|
71
84
|
|
72
85
|
Bugsnag.notify(BugsnagTestException.new("It crashed"))
|
73
86
|
end
|
74
87
|
|
75
|
-
it "
|
76
|
-
Bugsnag::Notification.
|
88
|
+
it "has the right exception message" do
|
89
|
+
expect(Bugsnag::Notification).to receive(:deliver_exception_payload) do |endpoint, payload|
|
77
90
|
exception = get_exception_from_payload(payload)
|
78
|
-
exception[:message].
|
91
|
+
expect(exception[:message]).to eq("It crashed")
|
79
92
|
end
|
80
93
|
|
81
94
|
Bugsnag.notify(BugsnagTestException.new("It crashed"))
|
82
95
|
end
|
83
96
|
|
84
|
-
it "
|
85
|
-
Bugsnag::Notification.
|
97
|
+
it "has a valid stacktrace" do
|
98
|
+
expect(Bugsnag::Notification).to receive(:deliver_exception_payload) do |endpoint, payload|
|
86
99
|
exception = get_exception_from_payload(payload)
|
87
|
-
exception[:stacktrace].length.
|
100
|
+
expect(exception[:stacktrace].length).to be > 0
|
88
101
|
end
|
89
102
|
|
90
103
|
Bugsnag.notify(BugsnagTestException.new("It crashed"))
|
91
104
|
end
|
92
105
|
|
93
|
-
|
94
|
-
|
106
|
+
# TODO: nested context
|
107
|
+
|
108
|
+
it "accepts tabs in overrides and adds them to metaData" do
|
109
|
+
expect(Bugsnag::Notification).to receive(:deliver_exception_payload) do |endpoint, payload|
|
95
110
|
event = get_event_from_payload(payload)
|
96
|
-
event[:metaData][:some_tab].
|
97
|
-
event[:metaData][:some_tab][:info].
|
98
|
-
event[:metaData][:some_tab][:data].
|
111
|
+
expect(event[:metaData][:some_tab]).not_to be_nil
|
112
|
+
expect(event[:metaData][:some_tab][:info]).to eq("here")
|
113
|
+
expect(event[:metaData][:some_tab][:data]).to eq("also here")
|
99
114
|
end
|
100
115
|
|
101
116
|
Bugsnag.notify(BugsnagTestException.new("It crashed"), {
|
@@ -106,12 +121,12 @@ describe Bugsnag::Notification do
|
|
106
121
|
})
|
107
122
|
end
|
108
123
|
|
109
|
-
it "
|
110
|
-
Bugsnag::Notification.
|
124
|
+
it "accepts non-hash overrides and adds them to the custom tab in metaData" do
|
125
|
+
expect(Bugsnag::Notification).to receive(:deliver_exception_payload) do |endpoint, payload|
|
111
126
|
event = get_event_from_payload(payload)
|
112
|
-
event[:metaData][:custom].
|
113
|
-
event[:metaData][:custom][:info].
|
114
|
-
event[:metaData][:custom][:data].
|
127
|
+
expect(event[:metaData][:custom]).not_to be_nil
|
128
|
+
expect(event[:metaData][:custom][:info]).to eq("here")
|
129
|
+
expect(event[:metaData][:custom][:data]).to eq("also here")
|
115
130
|
end
|
116
131
|
|
117
132
|
Bugsnag.notify(BugsnagTestException.new("It crashed"), {
|
@@ -120,12 +135,12 @@ describe Bugsnag::Notification do
|
|
120
135
|
})
|
121
136
|
end
|
122
137
|
|
123
|
-
it "
|
124
|
-
Bugsnag::Notification.
|
138
|
+
it "accepts meta data from an exception that mixes in Bugsnag::MetaData" do
|
139
|
+
expect(Bugsnag::Notification).to receive(:deliver_exception_payload) do |endpoint, payload|
|
125
140
|
event = get_event_from_payload(payload)
|
126
|
-
event[:metaData][:some_tab].
|
127
|
-
event[:metaData][:some_tab][:info].
|
128
|
-
event[:metaData][:some_tab][:data].
|
141
|
+
expect(event[:metaData][:some_tab]).not_to be_nil
|
142
|
+
expect(event[:metaData][:some_tab][:info]).to eq("here")
|
143
|
+
expect(event[:metaData][:some_tab][:data]).to eq("also here")
|
129
144
|
end
|
130
145
|
|
131
146
|
exception = BugsnagTestExceptionWithMetaData.new("It crashed")
|
@@ -138,13 +153,13 @@ describe Bugsnag::Notification do
|
|
138
153
|
|
139
154
|
Bugsnag.notify(exception)
|
140
155
|
end
|
141
|
-
|
142
|
-
it "
|
143
|
-
Bugsnag::Notification.
|
156
|
+
|
157
|
+
it "accepts meta data from an exception that mixes in Bugsnag::MetaData, but override using the overrides" do
|
158
|
+
expect(Bugsnag::Notification).to receive(:deliver_exception_payload) do |endpoint, payload|
|
144
159
|
event = get_event_from_payload(payload)
|
145
|
-
event[:metaData][:some_tab].
|
146
|
-
event[:metaData][:some_tab][:info].
|
147
|
-
event[:metaData][:some_tab][:data].
|
160
|
+
expect(event[:metaData][:some_tab]).not_to be_nil
|
161
|
+
expect(event[:metaData][:some_tab][:info]).to eq("overridden")
|
162
|
+
expect(event[:metaData][:some_tab][:data]).to eq("also here")
|
148
163
|
end
|
149
164
|
|
150
165
|
exception = BugsnagTestExceptionWithMetaData.new("It crashed")
|
@@ -157,11 +172,11 @@ describe Bugsnag::Notification do
|
|
157
172
|
|
158
173
|
Bugsnag.notify(exception, {:some_tab => {:info => "overridden"}})
|
159
174
|
end
|
160
|
-
|
161
|
-
it "
|
162
|
-
Bugsnag::Notification.
|
175
|
+
|
176
|
+
it "accepts user_id from an exception that mixes in Bugsnag::MetaData" do
|
177
|
+
expect(Bugsnag::Notification).to receive(:deliver_exception_payload) do |endpoint, payload|
|
163
178
|
event = get_event_from_payload(payload)
|
164
|
-
event[:user][:id].
|
179
|
+
expect(event[:user][:id]).to eq("exception_user_id")
|
165
180
|
end
|
166
181
|
|
167
182
|
exception = BugsnagTestExceptionWithMetaData.new("It crashed")
|
@@ -169,11 +184,11 @@ describe Bugsnag::Notification do
|
|
169
184
|
|
170
185
|
Bugsnag.notify(exception)
|
171
186
|
end
|
172
|
-
|
173
|
-
it "
|
174
|
-
Bugsnag::Notification.
|
187
|
+
|
188
|
+
it "accepts user_id from an exception that mixes in Bugsnag::MetaData, but override using the overrides" do
|
189
|
+
expect(Bugsnag::Notification).to receive(:deliver_exception_payload) do |endpoint, payload|
|
175
190
|
event = get_event_from_payload(payload)
|
176
|
-
event[:user][:id].
|
191
|
+
expect(event[:user][:id]).to eq("override_user_id")
|
177
192
|
end
|
178
193
|
|
179
194
|
exception = BugsnagTestExceptionWithMetaData.new("It crashed")
|
@@ -181,11 +196,11 @@ describe Bugsnag::Notification do
|
|
181
196
|
|
182
197
|
Bugsnag.notify(exception, {:user_id => "override_user_id"})
|
183
198
|
end
|
184
|
-
|
185
|
-
it "
|
186
|
-
Bugsnag::Notification.
|
199
|
+
|
200
|
+
it "accepts context from an exception that mixes in Bugsnag::MetaData" do
|
201
|
+
expect(Bugsnag::Notification).to receive(:deliver_exception_payload) do |endpoint, payload|
|
187
202
|
event = get_event_from_payload(payload)
|
188
|
-
event[:context].
|
203
|
+
expect(event[:context]).to eq("exception_context")
|
189
204
|
end
|
190
205
|
|
191
206
|
exception = BugsnagTestExceptionWithMetaData.new("It crashed")
|
@@ -193,11 +208,11 @@ describe Bugsnag::Notification do
|
|
193
208
|
|
194
209
|
Bugsnag.notify(exception)
|
195
210
|
end
|
196
|
-
|
197
|
-
it "
|
198
|
-
Bugsnag::Notification.
|
211
|
+
|
212
|
+
it "accept contexts from an exception that mixes in Bugsnag::MetaData, but override using the overrides" do
|
213
|
+
expect(Bugsnag::Notification).to receive(:deliver_exception_payload) do |endpoint, payload|
|
199
214
|
event = get_event_from_payload(payload)
|
200
|
-
event[:context].
|
215
|
+
expect(event[:context]).to eq("override_context")
|
201
216
|
end
|
202
217
|
|
203
218
|
exception = BugsnagTestExceptionWithMetaData.new("It crashed")
|
@@ -206,12 +221,12 @@ describe Bugsnag::Notification do
|
|
206
221
|
Bugsnag.notify(exception, {:context => "override_context"})
|
207
222
|
end
|
208
223
|
|
209
|
-
it "
|
210
|
-
Bugsnag::Notification.
|
224
|
+
it "accepts meta_data in overrides (for backwards compatibility) and merge it into metaData" do
|
225
|
+
expect(Bugsnag::Notification).to receive(:deliver_exception_payload) do |endpoint, payload|
|
211
226
|
event = get_event_from_payload(payload)
|
212
|
-
event[:metaData][:some_tab].
|
213
|
-
event[:metaData][:some_tab][:info].
|
214
|
-
event[:metaData][:some_tab][:data].
|
227
|
+
expect(event[:metaData][:some_tab]).not_to be_nil
|
228
|
+
expect(event[:metaData][:some_tab][:info]).to eq("here")
|
229
|
+
expect(event[:metaData][:some_tab][:data]).to eq("also here")
|
215
230
|
end
|
216
231
|
|
217
232
|
Bugsnag.notify(BugsnagTestException.new("It crashed"), {
|
@@ -224,11 +239,11 @@ describe Bugsnag::Notification do
|
|
224
239
|
})
|
225
240
|
end
|
226
241
|
|
227
|
-
it "
|
228
|
-
Bugsnag::Notification.
|
242
|
+
it "truncates large meta_data before sending" do
|
243
|
+
expect(Bugsnag::Notification).to receive(:post) do |endpoint, opts|
|
229
244
|
# Truncated body should be no bigger than
|
230
245
|
# 2 truncated hashes (4096*2) + rest of payload (5000)
|
231
|
-
opts[:body].length.
|
246
|
+
expect(opts[:body].length).to be < 4096*2 + 5000
|
232
247
|
end
|
233
248
|
|
234
249
|
Bugsnag.notify(BugsnagTestException.new("It crashed"), {
|
@@ -241,10 +256,10 @@ describe Bugsnag::Notification do
|
|
241
256
|
})
|
242
257
|
end
|
243
258
|
|
244
|
-
it "
|
245
|
-
Bugsnag::Notification.
|
259
|
+
it "accepts a severity in overrides" do
|
260
|
+
expect(Bugsnag::Notification).to receive(:deliver_exception_payload) do |endpoint, payload|
|
246
261
|
event = get_event_from_payload(payload)
|
247
|
-
event[:severity].
|
262
|
+
expect(event[:severity]).to eq("info")
|
248
263
|
end
|
249
264
|
|
250
265
|
Bugsnag.notify(BugsnagTestException.new("It crashed"), {
|
@@ -252,19 +267,19 @@ describe Bugsnag::Notification do
|
|
252
267
|
})
|
253
268
|
end
|
254
269
|
|
255
|
-
it "
|
256
|
-
Bugsnag::Notification.
|
270
|
+
it "defaults to error severity" do
|
271
|
+
expect(Bugsnag::Notification).to receive(:deliver_exception_payload) do |endpoint, payload|
|
257
272
|
event = get_event_from_payload(payload)
|
258
|
-
event[:severity].
|
273
|
+
expect(event[:severity]).to eq("error")
|
259
274
|
end
|
260
275
|
|
261
276
|
Bugsnag.notify(BugsnagTestException.new("It crashed"))
|
262
277
|
end
|
263
278
|
|
264
|
-
it "
|
265
|
-
Bugsnag::Notification.
|
279
|
+
it "does not accept a bad severity in overrides" do
|
280
|
+
expect(Bugsnag::Notification).to receive(:deliver_exception_payload) do |endpoint, payload|
|
266
281
|
event = get_event_from_payload(payload)
|
267
|
-
event[:severity].
|
282
|
+
expect(event[:severity]).to eq("error")
|
268
283
|
end
|
269
284
|
|
270
285
|
Bugsnag.notify(BugsnagTestException.new("It crashed"), {
|
@@ -272,19 +287,19 @@ describe Bugsnag::Notification do
|
|
272
287
|
})
|
273
288
|
end
|
274
289
|
|
275
|
-
it "
|
276
|
-
Bugsnag::Notification.
|
290
|
+
it "autonotifies fatal errors" do
|
291
|
+
expect(Bugsnag::Notification).to receive(:deliver_exception_payload) do |endpoint, payload|
|
277
292
|
event = get_event_from_payload(payload)
|
278
|
-
event[:severity].
|
293
|
+
expect(event[:severity]).to eq("fatal")
|
279
294
|
end
|
280
295
|
|
281
296
|
Bugsnag.auto_notify(BugsnagTestException.new("It crashed"))
|
282
297
|
end
|
283
298
|
|
284
|
-
it "
|
285
|
-
Bugsnag::Notification.
|
299
|
+
it "accepts a context in overrides" do
|
300
|
+
expect(Bugsnag::Notification).to receive(:deliver_exception_payload) do |endpoint, payload|
|
286
301
|
event = get_event_from_payload(payload)
|
287
|
-
event[:context].
|
302
|
+
expect(event[:context]).to eq("test_context")
|
288
303
|
end
|
289
304
|
|
290
305
|
Bugsnag.notify(BugsnagTestException.new("It crashed"), {
|
@@ -292,10 +307,10 @@ describe Bugsnag::Notification do
|
|
292
307
|
})
|
293
308
|
end
|
294
309
|
|
295
|
-
it "
|
296
|
-
Bugsnag::Notification.
|
310
|
+
it "accepts a user_id in overrides" do
|
311
|
+
expect(Bugsnag::Notification).to receive(:deliver_exception_payload) do |endpoint, payload|
|
297
312
|
event = get_event_from_payload(payload)
|
298
|
-
event[:user][:id].
|
313
|
+
expect(event[:user][:id]).to eq("test_user")
|
299
314
|
end
|
300
315
|
|
301
316
|
Bugsnag.notify(BugsnagTestException.new("It crashed"), {
|
@@ -303,40 +318,40 @@ describe Bugsnag::Notification do
|
|
303
318
|
})
|
304
319
|
end
|
305
320
|
|
306
|
-
it "
|
321
|
+
it "does not send a notification if auto_notify is false" do
|
307
322
|
Bugsnag.configure do |config|
|
308
323
|
config.auto_notify = false
|
309
324
|
end
|
310
325
|
|
311
|
-
Bugsnag::Notification.
|
326
|
+
expect(Bugsnag::Notification).not_to receive(:deliver_exception_payload)
|
312
327
|
|
313
328
|
Bugsnag.auto_notify(BugsnagTestException.new("It crashed"))
|
314
329
|
end
|
315
330
|
|
316
|
-
it "
|
331
|
+
it "contains a release_stage" do
|
317
332
|
Bugsnag.configure do |config|
|
318
333
|
config.release_stage = "production"
|
319
334
|
end
|
320
335
|
|
321
|
-
Bugsnag::Notification.
|
336
|
+
expect(Bugsnag::Notification).to receive(:deliver_exception_payload) do |endpoint, payload|
|
322
337
|
event = get_event_from_payload(payload)
|
323
|
-
event[:app][:releaseStage].
|
338
|
+
expect(event[:app][:releaseStage]).to eq("production")
|
324
339
|
end
|
325
340
|
|
326
341
|
Bugsnag.auto_notify(BugsnagTestException.new("It crashed"))
|
327
342
|
end
|
328
343
|
|
329
|
-
it "
|
330
|
-
Bugsnag::Notification.
|
344
|
+
it "respects the notify_release_stages setting by not sending in development" do
|
345
|
+
expect(Bugsnag::Notification).not_to receive(:deliver_exception_payload)
|
331
346
|
|
332
347
|
Bugsnag.configuration.notify_release_stages = ["production"]
|
333
348
|
Bugsnag.configuration.release_stage = "development"
|
334
|
-
|
349
|
+
|
335
350
|
Bugsnag.notify(BugsnagTestException.new("It crashed"))
|
336
351
|
end
|
337
352
|
|
338
|
-
it "
|
339
|
-
Bugsnag::Notification.
|
353
|
+
it "respects the notify_release_stages setting when set" do
|
354
|
+
expect(Bugsnag::Notification).to receive(:deliver_exception_payload) do |endpoint, payload|
|
340
355
|
exception = get_exception_from_payload(payload)
|
341
356
|
end
|
342
357
|
|
@@ -345,149 +360,149 @@ describe Bugsnag::Notification do
|
|
345
360
|
Bugsnag.notify(BugsnagTestException.new("It crashed"))
|
346
361
|
end
|
347
362
|
|
348
|
-
it "
|
349
|
-
Bugsnag::Notification.
|
350
|
-
endpoint.
|
363
|
+
it "uses the http://notify.bugsnag.com endpoint by default" do
|
364
|
+
expect(Bugsnag::Notification).to receive(:deliver_exception_payload) do |endpoint, payload|
|
365
|
+
expect(endpoint).to eq("http://notify.bugsnag.com")
|
351
366
|
end
|
352
367
|
|
353
368
|
Bugsnag.notify(BugsnagTestException.new("It crashed"))
|
354
369
|
end
|
355
370
|
|
356
|
-
it "
|
357
|
-
Bugsnag::Notification.
|
358
|
-
endpoint.
|
371
|
+
it "uses ssl when use_ssl is true" do
|
372
|
+
expect(Bugsnag::Notification).to receive(:deliver_exception_payload) do |endpoint, payload|
|
373
|
+
expect(endpoint).to start_with "https://"
|
359
374
|
end
|
360
375
|
|
361
376
|
Bugsnag.configuration.use_ssl = true
|
362
377
|
Bugsnag.notify(BugsnagTestException.new("It crashed"))
|
363
378
|
end
|
364
379
|
|
365
|
-
it "
|
366
|
-
Bugsnag::Notification.
|
367
|
-
endpoint.
|
380
|
+
it "does not use ssl when use_ssl is false" do
|
381
|
+
expect(Bugsnag::Notification).to receive(:deliver_exception_payload) do |endpoint, payload|
|
382
|
+
expect(endpoint).to start_with "http://"
|
368
383
|
end
|
369
384
|
|
370
385
|
Bugsnag.configuration.use_ssl = false
|
371
386
|
Bugsnag.notify(BugsnagTestException.new("It crashed"))
|
372
387
|
end
|
373
388
|
|
374
|
-
it "
|
375
|
-
Bugsnag::Notification.
|
376
|
-
endpoint.
|
389
|
+
it "does not use ssl when use_ssl is unset" do
|
390
|
+
expect(Bugsnag::Notification).to receive(:deliver_exception_payload) do |endpoint, payload|
|
391
|
+
expect(endpoint).to start_with "http://"
|
377
392
|
end
|
378
393
|
|
379
394
|
Bugsnag.notify(BugsnagTestException.new("It crashed"))
|
380
395
|
end
|
381
396
|
|
382
|
-
it "
|
383
|
-
Bugsnag::Notification.
|
397
|
+
it "does not mark the top-most stacktrace line as inProject if out of project" do
|
398
|
+
expect(Bugsnag::Notification).to receive(:deliver_exception_payload) do |endpoint, payload|
|
384
399
|
exception = get_exception_from_payload(payload)
|
385
|
-
exception[:stacktrace].
|
386
|
-
exception[:stacktrace].first[:inProject].
|
400
|
+
expect(exception[:stacktrace].size).to be >= 1
|
401
|
+
expect(exception[:stacktrace].first[:inProject]).to be_nil
|
387
402
|
end
|
388
403
|
|
389
404
|
Bugsnag.configuration.project_root = "/Random/location/here"
|
390
405
|
Bugsnag.notify(BugsnagTestException.new("It crashed"))
|
391
406
|
end
|
392
407
|
|
393
|
-
it "
|
394
|
-
Bugsnag::Notification.
|
408
|
+
it "marks the top-most stacktrace line as inProject if necessary" do
|
409
|
+
expect(Bugsnag::Notification).to receive(:deliver_exception_payload) do |endpoint, payload|
|
395
410
|
exception = get_exception_from_payload(payload)
|
396
|
-
exception[:stacktrace].
|
397
|
-
exception[:stacktrace].first[:inProject].
|
411
|
+
expect(exception[:stacktrace].size).to be >= 1
|
412
|
+
expect(exception[:stacktrace].first[:inProject]).to eq(true)
|
398
413
|
end
|
399
414
|
|
400
415
|
Bugsnag.configuration.project_root = File.expand_path File.dirname(__FILE__)
|
401
416
|
Bugsnag.notify(BugsnagTestException.new("It crashed"))
|
402
417
|
end
|
403
418
|
|
404
|
-
it "
|
405
|
-
Bugsnag::Notification.
|
419
|
+
it "adds app_version to the payload if it is set" do
|
420
|
+
expect(Bugsnag::Notification).to receive(:deliver_exception_payload) do |endpoint, payload|
|
406
421
|
event = get_event_from_payload(payload)
|
407
|
-
event[:app][:version].
|
422
|
+
expect(event[:app][:version]).to eq("1.1.1")
|
408
423
|
end
|
409
424
|
|
410
425
|
Bugsnag.configuration.app_version = "1.1.1"
|
411
426
|
Bugsnag.notify(BugsnagTestException.new("It crashed"))
|
412
427
|
end
|
413
428
|
|
414
|
-
it "
|
415
|
-
Bugsnag::Notification.
|
429
|
+
it "filters params from all payload hashes if they are set in default params_filters" do
|
430
|
+
expect(Bugsnag::Notification).to receive(:deliver_exception_payload) do |endpoint, payload|
|
416
431
|
event = get_event_from_payload(payload)
|
417
|
-
event[:metaData].
|
418
|
-
event[:metaData][:request].
|
419
|
-
event[:metaData][:request][:params].
|
420
|
-
event[:metaData][:request][:params][:password].
|
421
|
-
event[:metaData][:request][:params][:other_password].
|
422
|
-
event[:metaData][:request][:params][:other_data].
|
432
|
+
expect(event[:metaData]).not_to be_nil
|
433
|
+
expect(event[:metaData][:request]).not_to be_nil
|
434
|
+
expect(event[:metaData][:request][:params]).not_to be_nil
|
435
|
+
expect(event[:metaData][:request][:params][:password]).to eq("[FILTERED]")
|
436
|
+
expect(event[:metaData][:request][:params][:other_password]).to eq("[FILTERED]")
|
437
|
+
expect(event[:metaData][:request][:params][:other_data]).to eq("123456")
|
423
438
|
end
|
424
439
|
|
425
440
|
Bugsnag.notify(BugsnagTestException.new("It crashed"), {:request => {:params => {:password => "1234", :other_password => "12345", :other_data => "123456"}}})
|
426
441
|
end
|
427
442
|
|
428
|
-
it "
|
429
|
-
Bugsnag::Notification.
|
443
|
+
it "filters params from all payload hashes if they are added to params_filters" do
|
444
|
+
expect(Bugsnag::Notification).to receive(:deliver_exception_payload) do |endpoint, payload|
|
430
445
|
event = get_event_from_payload(payload)
|
431
|
-
event[:metaData].
|
432
|
-
event[:metaData][:request].
|
433
|
-
event[:metaData][:request][:params].
|
434
|
-
event[:metaData][:request][:params][:password].
|
435
|
-
event[:metaData][:request][:params][:other_password].
|
436
|
-
event[:metaData][:request][:params][:other_data].
|
446
|
+
expect(event[:metaData]).not_to be_nil
|
447
|
+
expect(event[:metaData][:request]).not_to be_nil
|
448
|
+
expect(event[:metaData][:request][:params]).not_to be_nil
|
449
|
+
expect(event[:metaData][:request][:params][:password]).to eq("[FILTERED]")
|
450
|
+
expect(event[:metaData][:request][:params][:other_password]).to eq("[FILTERED]")
|
451
|
+
expect(event[:metaData][:request][:params][:other_data]).to eq("[FILTERED]")
|
437
452
|
end
|
438
453
|
|
439
454
|
Bugsnag.configuration.params_filters << "other_data"
|
440
455
|
Bugsnag.notify(BugsnagTestException.new("It crashed"), {:request => {:params => {:password => "1234", :other_password => "123456", :other_data => "123456"}}})
|
441
456
|
end
|
442
457
|
|
443
|
-
it "
|
444
|
-
Bugsnag::Notification.
|
458
|
+
it "does not filter params from payload hashes if their values are nil" do
|
459
|
+
expect(Bugsnag::Notification).to receive(:deliver_exception_payload) do |endpoint, payload|
|
445
460
|
event = get_event_from_payload(payload)
|
446
|
-
event[:metaData].
|
447
|
-
event[:metaData][:request].
|
448
|
-
event[:metaData][:request][:params].
|
449
|
-
event[:metaData][:request][:params].
|
461
|
+
expect(event[:metaData]).not_to be_nil
|
462
|
+
expect(event[:metaData][:request]).not_to be_nil
|
463
|
+
expect(event[:metaData][:request][:params]).not_to be_nil
|
464
|
+
expect(event[:metaData][:request][:params]).to have_key(:nil_param)
|
450
465
|
end
|
451
466
|
|
452
467
|
Bugsnag.notify(BugsnagTestException.new("It crashed"), {:request => {:params => {:nil_param => nil}}})
|
453
468
|
end
|
454
469
|
|
455
|
-
it "
|
456
|
-
Bugsnag::Notification.
|
470
|
+
it "does not notify if the exception class is in the default ignore_classes list" do
|
471
|
+
expect(Bugsnag::Notification).not_to receive(:deliver_exception_payload)
|
457
472
|
|
458
473
|
Bugsnag.notify_or_ignore(ActiveRecord::RecordNotFound.new("It crashed"))
|
459
474
|
end
|
460
475
|
|
461
|
-
it "
|
476
|
+
it "does not notify if the non-default exception class is added to the ignore_classes" do
|
462
477
|
Bugsnag.configuration.ignore_classes << "BugsnagTestException"
|
463
478
|
|
464
|
-
Bugsnag::Notification.
|
479
|
+
expect(Bugsnag::Notification).not_to receive(:deliver_exception_payload)
|
465
480
|
|
466
481
|
Bugsnag.notify_or_ignore(BugsnagTestException.new("It crashed"))
|
467
482
|
end
|
468
483
|
|
469
|
-
it "
|
484
|
+
it "does not notify if the exception is matched by an ignore_classes lambda function" do
|
470
485
|
Bugsnag.configuration.ignore_classes << lambda {|e| e.message =~ /crashed/}
|
471
486
|
|
472
|
-
Bugsnag::Notification.
|
487
|
+
expect(Bugsnag::Notification).not_to receive(:deliver_exception_payload)
|
473
488
|
|
474
489
|
Bugsnag.notify_or_ignore(BugsnagTestException.new("It crashed"))
|
475
490
|
end
|
476
491
|
|
477
|
-
it "
|
492
|
+
it "does not notify if the user agent is present and matches a regex in ignore_user_agents" do
|
478
493
|
Bugsnag.configuration.ignore_user_agents << %r{BugsnagUserAgent}
|
479
494
|
|
480
|
-
Bugsnag::Notification.
|
495
|
+
expect(Bugsnag::Notification).not_to receive(:deliver_exception_payload)
|
481
496
|
|
482
497
|
((Thread.current["bugsnag_req_data"] ||= {})[:rack_env] ||= {})["HTTP_USER_AGENT"] = "BugsnagUserAgent"
|
483
498
|
|
484
499
|
Bugsnag.notify_or_ignore(BugsnagTestException.new("It crashed"))
|
485
500
|
end
|
486
501
|
|
487
|
-
it "
|
488
|
-
Bugsnag::Notification.
|
502
|
+
it "sends the cause of the exception" do
|
503
|
+
expect(Bugsnag::Notification).to receive(:deliver_exception_payload) do |endpoint, payload|
|
489
504
|
event = get_event_from_payload(payload)
|
490
|
-
event[:exceptions].
|
505
|
+
expect(event[:exceptions].size).to eq(2)
|
491
506
|
end
|
492
507
|
|
493
508
|
begin
|
@@ -501,10 +516,10 @@ describe Bugsnag::Notification do
|
|
501
516
|
end
|
502
517
|
end
|
503
518
|
|
504
|
-
it "
|
505
|
-
Bugsnag::Notification.
|
519
|
+
it "does not unwrap the same exception twice" do
|
520
|
+
expect(Bugsnag::Notification).to receive(:deliver_exception_payload) do |endpoint, payload|
|
506
521
|
event = get_event_from_payload(payload)
|
507
|
-
event[:exceptions].
|
522
|
+
expect(event[:exceptions].size).to eq(1)
|
508
523
|
end
|
509
524
|
|
510
525
|
ex = NestedException.new("Self-referential exception")
|
@@ -513,10 +528,10 @@ describe Bugsnag::Notification do
|
|
513
528
|
Bugsnag.notify_or_ignore(ex)
|
514
529
|
end
|
515
530
|
|
516
|
-
it "
|
517
|
-
Bugsnag::Notification.
|
531
|
+
it "does not unwrap more than 5 exceptions" do
|
532
|
+
expect(Bugsnag::Notification).to receive(:deliver_exception_payload) do |endpoint, payload|
|
518
533
|
event = get_event_from_payload(payload)
|
519
|
-
event[:exceptions].
|
534
|
+
expect(event[:exceptions].size).to eq(5)
|
520
535
|
end
|
521
536
|
|
522
537
|
first_ex = ex = NestedException.new("Deep exception")
|
@@ -527,110 +542,110 @@ describe Bugsnag::Notification do
|
|
527
542
|
Bugsnag.notify_or_ignore(first_ex)
|
528
543
|
end
|
529
544
|
|
530
|
-
it "
|
531
|
-
Bugsnag::Notification.
|
545
|
+
it "calls to_exception on i18n error objects" do
|
546
|
+
expect(Bugsnag::Notification).to receive(:deliver_exception_payload) do |endpoint, payload|
|
532
547
|
exception = get_exception_from_payload(payload)
|
533
|
-
exception[:errorClass].
|
534
|
-
exception[:message].
|
548
|
+
expect(exception[:errorClass]).to eq("BugsnagTestException")
|
549
|
+
expect(exception[:message]).to eq("message")
|
535
550
|
end
|
536
551
|
|
537
552
|
Bugsnag.notify(OpenStruct.new(:to_exception => BugsnagTestException.new("message")))
|
538
553
|
end
|
539
554
|
|
540
|
-
it "
|
541
|
-
Bugsnag::Notification.
|
555
|
+
it "generates runtimeerror for non exceptions" do
|
556
|
+
expect(Bugsnag::Notification).to receive(:deliver_exception_payload) do |endpoint, payload|
|
542
557
|
exception = get_exception_from_payload(payload)
|
543
|
-
exception[:errorClass].
|
544
|
-
exception[:message].
|
558
|
+
expect(exception[:errorClass]).to eq("RuntimeError")
|
559
|
+
expect(exception[:message]).to eq("test message")
|
545
560
|
end
|
546
561
|
|
547
|
-
|
562
|
+
notify_test_exception
|
548
563
|
end
|
549
564
|
|
550
|
-
it "
|
565
|
+
it "supports unix-style paths in backtraces" do
|
551
566
|
ex = BugsnagTestException.new("It crashed")
|
552
567
|
ex.set_backtrace([
|
553
568
|
"/Users/james/app/spec/notification_spec.rb:419",
|
554
569
|
"/Some/path/rspec/example.rb:113:in `instance_eval'"
|
555
570
|
])
|
556
571
|
|
557
|
-
Bugsnag::Notification.
|
572
|
+
expect(Bugsnag::Notification).to receive(:deliver_exception_payload) do |endpoint, payload|
|
558
573
|
exception = get_exception_from_payload(payload)
|
559
|
-
exception[:stacktrace].length.
|
574
|
+
expect(exception[:stacktrace].length).to eq(2)
|
560
575
|
|
561
576
|
line = exception[:stacktrace][0]
|
562
|
-
line[:file].
|
563
|
-
line[:lineNumber].
|
564
|
-
line[:method].
|
577
|
+
expect(line[:file]).to eq("/Users/james/app/spec/notification_spec.rb")
|
578
|
+
expect(line[:lineNumber]).to eq(419)
|
579
|
+
expect(line[:method]).to be nil
|
565
580
|
|
566
581
|
line = exception[:stacktrace][1]
|
567
|
-
line[:file].
|
568
|
-
line[:lineNumber].
|
569
|
-
line[:method].
|
582
|
+
expect(line[:file]).to eq("/Some/path/rspec/example.rb")
|
583
|
+
expect(line[:lineNumber]).to eq(113)
|
584
|
+
expect(line[:method]).to eq("instance_eval")
|
570
585
|
end
|
571
586
|
|
572
587
|
Bugsnag.notify(ex)
|
573
588
|
end
|
574
589
|
|
575
|
-
it "
|
590
|
+
it "supports windows-style paths in backtraces" do
|
576
591
|
ex = BugsnagTestException.new("It crashed")
|
577
592
|
ex.set_backtrace([
|
578
593
|
"C:/projects/test/app/controllers/users_controller.rb:13:in `index'",
|
579
594
|
"C:/ruby/1.9.1/gems/actionpack-2.3.10/filters.rb:638:in `block in run_before_filters'"
|
580
595
|
])
|
581
596
|
|
582
|
-
Bugsnag::Notification.
|
597
|
+
expect(Bugsnag::Notification).to receive(:deliver_exception_payload) do |endpoint, payload|
|
583
598
|
exception = get_exception_from_payload(payload)
|
584
|
-
exception[:stacktrace].length.
|
599
|
+
expect(exception[:stacktrace].length).to eq(2)
|
585
600
|
|
586
601
|
line = exception[:stacktrace][0]
|
587
|
-
line[:file].
|
588
|
-
line[:lineNumber].
|
589
|
-
line[:method].
|
602
|
+
expect(line[:file]).to eq("C:/projects/test/app/controllers/users_controller.rb")
|
603
|
+
expect(line[:lineNumber]).to eq(13)
|
604
|
+
expect(line[:method]).to eq("index")
|
590
605
|
|
591
606
|
line = exception[:stacktrace][1]
|
592
|
-
line[:file].
|
593
|
-
line[:lineNumber].
|
594
|
-
line[:method].
|
607
|
+
expect(line[:file]).to eq("C:/ruby/1.9.1/gems/actionpack-2.3.10/filters.rb")
|
608
|
+
expect(line[:lineNumber]).to eq(638)
|
609
|
+
expect(line[:method]).to eq("block in run_before_filters")
|
595
610
|
end
|
596
611
|
|
597
612
|
Bugsnag.notify(ex)
|
598
613
|
end
|
599
614
|
|
600
|
-
it "
|
615
|
+
it "uses a proxy host if configured" do
|
601
616
|
Bugsnag.configure do |config|
|
602
617
|
config.proxy_host = "host_name"
|
603
618
|
end
|
604
619
|
|
605
|
-
Bugsnag::Notification.
|
606
|
-
args.length.
|
607
|
-
args[0].
|
608
|
-
args[1].
|
609
|
-
args[2].
|
610
|
-
args[3].
|
620
|
+
expect(Bugsnag::Notification).to receive(:http_proxy) do |*args|
|
621
|
+
expect(args.length).to eq(4)
|
622
|
+
expect(args[0]).to eq("host_name")
|
623
|
+
expect(args[1]).to eq(nil)
|
624
|
+
expect(args[2]).to eq(nil)
|
625
|
+
expect(args[3]).to eq(nil)
|
611
626
|
end
|
612
627
|
|
613
|
-
|
628
|
+
notify_test_exception
|
614
629
|
end
|
615
630
|
|
616
|
-
it "
|
631
|
+
it "uses a proxy host/port if configured" do
|
617
632
|
Bugsnag.configure do |config|
|
618
633
|
config.proxy_host = "host_name"
|
619
634
|
config.proxy_port = 1234
|
620
635
|
end
|
621
636
|
|
622
|
-
Bugsnag::Notification.
|
623
|
-
args.length.
|
624
|
-
args[0].
|
625
|
-
args[1].
|
626
|
-
args[2].
|
627
|
-
args[3].
|
637
|
+
expect(Bugsnag::Notification).to receive(:http_proxy) do |*args|
|
638
|
+
expect(args.length).to eq(4)
|
639
|
+
expect(args[0]).to eq("host_name")
|
640
|
+
expect(args[1]).to eq(1234)
|
641
|
+
expect(args[2]).to eq(nil)
|
642
|
+
expect(args[3]).to eq(nil)
|
628
643
|
end
|
629
644
|
|
630
|
-
|
645
|
+
notify_test_exception
|
631
646
|
end
|
632
647
|
|
633
|
-
it "
|
648
|
+
it "uses a proxy host/port/user/pass if configured" do
|
634
649
|
Bugsnag.configure do |config|
|
635
650
|
config.proxy_host = "host_name"
|
636
651
|
config.proxy_port = 1234
|
@@ -638,27 +653,27 @@ describe Bugsnag::Notification do
|
|
638
653
|
config.proxy_password = "password"
|
639
654
|
end
|
640
655
|
|
641
|
-
Bugsnag::Notification.
|
642
|
-
args.length.
|
643
|
-
args[0].
|
644
|
-
args[1].
|
645
|
-
args[2].
|
646
|
-
args[3].
|
656
|
+
expect(Bugsnag::Notification).to receive(:http_proxy) do |*args|
|
657
|
+
expect(args.length).to eq(4)
|
658
|
+
expect(args[0]).to eq("host_name")
|
659
|
+
expect(args[1]).to eq(1234)
|
660
|
+
expect(args[2]).to eq("user")
|
661
|
+
expect(args[3]).to eq("password")
|
647
662
|
end
|
648
663
|
|
649
|
-
|
664
|
+
notify_test_exception
|
650
665
|
end
|
651
666
|
|
652
|
-
it "
|
667
|
+
it "sets the timeout time to the value in the configuration" do
|
653
668
|
Bugsnag.configure do |config|
|
654
669
|
config.timeout = 10
|
655
670
|
end
|
656
671
|
|
657
|
-
Bugsnag::Notification.
|
658
|
-
args.length.
|
659
|
-
args[0].
|
672
|
+
expect(Bugsnag::Notification).to receive(:default_timeout) do |*args|
|
673
|
+
expect(args.length).to eq(1)
|
674
|
+
expect(args[0]).to eq(10)
|
660
675
|
end
|
661
676
|
|
662
|
-
|
677
|
+
notify_test_exception
|
663
678
|
end
|
664
679
|
end
|