bugsnag 5.5.0 → 6.0.0

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 (67) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +33 -11
  3. data/CHANGELOG.md +23 -0
  4. data/Gemfile +20 -0
  5. data/Rakefile +19 -12
  6. data/UPGRADING.md +58 -0
  7. data/VERSION +1 -1
  8. data/bugsnag.gemspec +0 -9
  9. data/lib/bugsnag.rb +64 -86
  10. data/lib/bugsnag/configuration.rb +42 -26
  11. data/lib/bugsnag/delivery.rb +9 -0
  12. data/lib/bugsnag/delivery/synchronous.rb +3 -5
  13. data/lib/bugsnag/delivery/thread_queue.rb +4 -2
  14. data/lib/bugsnag/helpers.rb +5 -16
  15. data/lib/bugsnag/{delayed_job.rb → integrations/delayed_job.rb} +15 -7
  16. data/lib/bugsnag/{mailman.rb → integrations/mailman.rb} +13 -11
  17. data/lib/bugsnag/{que.rb → integrations/que.rb} +11 -11
  18. data/lib/bugsnag/{rack.rb → integrations/rack.rb} +22 -23
  19. data/lib/bugsnag/{rails → integrations/rails}/active_record_rescue.rb +9 -7
  20. data/lib/bugsnag/{rails → integrations/rails}/controller_methods.rb +0 -9
  21. data/lib/bugsnag/{railtie.rb → integrations/railtie.rb} +24 -21
  22. data/lib/bugsnag/{rake.rb → integrations/rake.rb} +12 -9
  23. data/lib/bugsnag/{resque.rb → integrations/resque.rb} +12 -9
  24. data/lib/bugsnag/integrations/shoryuken.rb +49 -0
  25. data/lib/bugsnag/{sidekiq.rb → integrations/sidekiq.rb} +13 -9
  26. data/lib/bugsnag/middleware/callbacks.rb +4 -8
  27. data/lib/bugsnag/middleware/classify_error.rb +7 -13
  28. data/lib/bugsnag/middleware/clearance_user.rb +8 -8
  29. data/lib/bugsnag/middleware/exception_meta_data.rb +34 -0
  30. data/lib/bugsnag/middleware/ignore_error_class.rb +21 -0
  31. data/lib/bugsnag/middleware/mailman.rb +4 -4
  32. data/lib/bugsnag/middleware/rack_request.rb +13 -13
  33. data/lib/bugsnag/middleware/rails3_request.rb +10 -10
  34. data/lib/bugsnag/middleware/rake.rb +5 -5
  35. data/lib/bugsnag/middleware/sidekiq.rb +5 -5
  36. data/lib/bugsnag/middleware/suggestion_data.rb +30 -0
  37. data/lib/bugsnag/middleware/warden_user.rb +6 -6
  38. data/lib/bugsnag/middleware_stack.rb +5 -5
  39. data/lib/bugsnag/report.rb +187 -0
  40. data/lib/bugsnag/stacktrace.rb +113 -0
  41. data/lib/bugsnag/tasks/bugsnag.rake +2 -70
  42. data/spec/cleaner_spec.rb +6 -0
  43. data/spec/configuration_spec.rb +1 -1
  44. data/spec/fixtures/middleware/internal_info_setter.rb +3 -3
  45. data/spec/fixtures/middleware/public_info_setter.rb +3 -3
  46. data/spec/fixtures/tasks/Rakefile +2 -3
  47. data/spec/integration_spec.rb +5 -20
  48. data/spec/{delayed_job_spec.rb → integrations/delayed_job_spec.rb} +0 -0
  49. data/spec/integrations/sidekiq_spec.rb +34 -0
  50. data/spec/middleware_spec.rb +108 -35
  51. data/spec/rack_spec.rb +1 -1
  52. data/spec/{notification_spec.rb → report_spec.rb} +226 -209
  53. data/spec/spec_helper.rb +18 -0
  54. data/spec/{code_spec.rb → stacktrace_spec.rb} +1 -1
  55. metadata +23 -139
  56. data/.document +0 -5
  57. data/lib/bugsnag/capistrano.rb +0 -7
  58. data/lib/bugsnag/capistrano2.rb +0 -32
  59. data/lib/bugsnag/delay/resque.rb +0 -21
  60. data/lib/bugsnag/deploy.rb +0 -35
  61. data/lib/bugsnag/middleware/rails2_request.rb +0 -52
  62. data/lib/bugsnag/notification.rb +0 -506
  63. data/lib/bugsnag/rails.rb +0 -70
  64. data/lib/bugsnag/rails/action_controller_rescue.rb +0 -74
  65. data/lib/bugsnag/shoryuken.rb +0 -41
  66. data/lib/bugsnag/tasks/bugsnag.cap +0 -48
  67. data/rails/init.rb +0 -7
@@ -42,6 +42,12 @@ describe Bugsnag::Cleaner do
42
42
  expect(subject.clean_object(obj)).to eq("André")
43
43
  end
44
44
 
45
+ it "cleans custom objects" do
46
+ class Macaron; end
47
+ a = Macaron.new
48
+ expect(subject.clean_object(a)).to eq('[OBJECT]')
49
+ end
50
+
45
51
  it "cleans up binary strings properly" do
46
52
  if RUBY_VERSION > "1.9"
47
53
  obj = "Andr\xc7\xff"
@@ -4,7 +4,7 @@ require 'spec_helper'
4
4
  describe Bugsnag::Configuration do
5
5
  describe "delivery_method" do
6
6
  it "should have the default delivery method" do
7
- expect(subject.delivery_method).to eq(Bugsnag::Configuration::DEFAULT_DELIVERY_METHOD)
7
+ expect(subject.delivery_method).to eq(:thread_queue)
8
8
  end
9
9
 
10
10
  it "should have the defined delivery_method" do
@@ -4,8 +4,8 @@ class InternalInfoSetter
4
4
  @bugsnag = bugsnag
5
5
  end
6
6
 
7
- def call(notification)
8
- notification.meta_data[:custom][:info] = MESSAGE
9
- @bugsnag.call(notification)
7
+ def call(report)
8
+ report.meta_data.merge!({custom: {info: MESSAGE}})
9
+ @bugsnag.call(report)
10
10
  end
11
11
  end
@@ -4,8 +4,8 @@ class PublicInfoSetter
4
4
  @bugsnag = bugsnag
5
5
  end
6
6
 
7
- def call(notification)
8
- notification.meta_data[:custom][:info] = MESSAGE
9
- @bugsnag.call(notification)
7
+ def call(report)
8
+ report.meta_data.merge!({custom: {info: MESSAGE}})
9
+ @bugsnag.call(report)
10
10
  end
11
11
  end
@@ -1,13 +1,12 @@
1
- require "bugsnag/rake"
1
+ require "bugsnag/integrations/rake"
2
2
 
3
3
  namespace :test do
4
4
  desc "used by integration_spec to test that Bugsnag::Middleware::Rake runs properly"
5
5
  task :crash do
6
6
  port = ENV['BUGSNAG_TEST_SERVER_PORT']
7
7
  Bugsnag.configure do |config|
8
- config.endpoint = "localhost:#{port}"
8
+ config.endpoint = "http://localhost:#{port}"
9
9
  config.api_key = "0" * 32
10
- config.use_ssl = false
11
10
  end
12
11
 
13
12
  raise
@@ -15,6 +15,7 @@ describe 'Bugsnag' do
15
15
  end
16
16
  Thread.new{ server.start }
17
17
  end
18
+
18
19
  after do
19
20
  server.stop
20
21
  queue.clear
@@ -39,8 +40,7 @@ describe 'Bugsnag' do
39
40
 
40
41
  it 'should send notifications over the wire' do
41
42
  Bugsnag.configure do |config|
42
- config.endpoint = "localhost:#{server.config[:Port]}"
43
- config.use_ssl = false
43
+ config.endpoint = "http://localhost:#{server.config[:Port]}"
44
44
  end
45
45
  WebMock.allow_net_connect!
46
46
 
@@ -49,22 +49,9 @@ describe 'Bugsnag' do
49
49
  expect(request['events'][0]['exceptions'][0]['message']).to eq('yo')
50
50
  end
51
51
 
52
- it 'should send deploys over the wire' do
53
- Bugsnag.configure do |config|
54
- config.endpoint = "localhost:#{server.config[:Port]}"
55
- config.use_ssl = false
56
- end
57
- WebMock.allow_net_connect!
58
-
59
- Bugsnag::Deploy.notify :app_version => '1.1.1'
60
-
61
- expect(request['appVersion']).to eq('1.1.1')
62
- end
63
-
64
52
  it 'should work with threadpool delivery' do
65
53
  Bugsnag.configure do |config|
66
- config.endpoint = "localhost:#{server.config[:Port]}"
67
- config.use_ssl = false
54
+ config.endpoint = "http://localhost:#{server.config[:Port]}"
68
55
  config.delivery_method = :thread_queue
69
56
  end
70
57
  WebMock.allow_net_connect!
@@ -78,8 +65,7 @@ describe 'Bugsnag' do
78
65
  is_jruby = defined?(RUBY_ENGINE) && RUBY_ENGINE == 'jruby'
79
66
  unless is_jruby #jruby doesn't support fork, so this test doesn't apply
80
67
  Bugsnag.configure do |config|
81
- config.endpoint = "localhost:#{server.config[:Port]}"
82
- config.use_ssl = false
68
+ config.endpoint = "http://localhost:#{server.config[:Port]}"
83
69
  config.delivery_method = :thread_queue
84
70
  end
85
71
  WebMock.allow_net_connect!
@@ -117,8 +103,7 @@ describe 'Bugsnag' do
117
103
  it 'should use a proxy when configured' do
118
104
  Bugsnag.configure do |config|
119
105
 
120
- config.endpoint = "localhost:#{server.config[:Port]}"
121
- config.use_ssl = false
106
+ config.endpoint = "http://localhost:#{server.config[:Port]}"
122
107
 
123
108
  config.proxy_host = 'localhost'
124
109
  config.proxy_port = proxy.config[:Port]
@@ -0,0 +1,34 @@
1
+ require 'spec_helper'
2
+ require 'sidekiq/testing'
3
+
4
+ class FailingWorker
5
+ include Sidekiq::Worker
6
+ def perform(value)
7
+ puts "Work: #{100/value}"
8
+ end
9
+ end
10
+
11
+ describe Bugsnag::Sidekiq do
12
+ before do
13
+ Sidekiq::Testing.inline!
14
+ Sidekiq::Testing.server_middleware do |chain|
15
+ chain.add Bugsnag::Sidekiq
16
+ end
17
+ end
18
+
19
+ it "works" do
20
+ begin
21
+ FailingWorker.perform_async(-0)
22
+ fail("shouldn't be here")
23
+ rescue
24
+ end
25
+
26
+ expect(Bugsnag).to have_sent_notification {|payload|
27
+ event = get_event_from_payload(payload)
28
+ expect(event["metaData"]["sidekiq"]["msg"]["class"]).to eq("FailingWorker")
29
+ expect(event["metaData"]["sidekiq"]["msg"]["args"]).to eq([-0])
30
+ expect(event["metaData"]["sidekiq"]["msg"]["queue"]).to eq("default")
31
+ expect(event["severity"]).to eq("error")
32
+ }
33
+ end
34
+ end
@@ -28,8 +28,8 @@ describe Bugsnag::MiddlewareStack do
28
28
  it "runs before_bugsnag_notify callbacks, adding custom data" do
29
29
  callback_run_count = 0
30
30
  Bugsnag.before_notify_callbacks << lambda {|notif|
31
- notif.add_custom_data(:info, "here")
32
- notif.add_custom_data(:data, "also here")
31
+ notif.add_tab(:custom, {info: "here"})
32
+ notif.add_tab(:custom, {data: "also here"})
33
33
 
34
34
  callback_run_count += 1
35
35
  }
@@ -67,34 +67,35 @@ describe Bugsnag::MiddlewareStack do
67
67
 
68
68
  end
69
69
 
70
- it "allows overrides to override values set by internal middleware" do
70
+ it "allows block to override values set by internal middleware" do
71
71
  Bugsnag.configuration.internal_middleware.use(InternalInfoSetter)
72
- Bugsnag.notify(BugsnagTestException.new("It crashed"), {:info => "overridden"})
72
+ Bugsnag.notify(BugsnagTestException.new("It crashed")) do |report|
73
+ report.meta_data.merge!({custom: {info: 'overridden'}})
74
+ end
73
75
 
74
76
  expect(Bugsnag).to have_sent_notification{ |payload|
75
77
  event = get_event_from_payload(payload)
76
78
  expect(event["metaData"]["custom"]).not_to be_nil
77
- expect(event["metaData"]["custom"]["info"]).not_to eq(InternalInfoSetter::MESSAGE)
78
79
  expect(event["metaData"]["custom"]["info"]).to eq("overridden")
79
80
  }
80
81
  end
81
82
 
82
- it "doesn't allow overrides to override public middleware" do
83
+ it "allows block to override public middleware" do
83
84
  Bugsnag.configuration.middleware.use(PublicInfoSetter)
84
85
 
85
- Bugsnag.notify(BugsnagTestException.new("It crashed"), {:info => "overridden"})
86
+ Bugsnag.notify(BugsnagTestException.new("It crashed")) do |report|
87
+ report.meta_data.merge!({custom: {info: 'overridden'}})
88
+ end
86
89
 
87
90
  expect(Bugsnag).to have_sent_notification{ |payload|
88
91
  event = get_event_from_payload(payload)
89
92
  expect(event["metaData"]["custom"]).not_to be_nil
90
- expect(event["metaData"]["custom"]["info"]).not_to eq("overridden")
91
- expect(event["metaData"]["custom"]["info"]).to eq(PublicInfoSetter::MESSAGE)
93
+ expect(event["metaData"]["custom"]["info"]).to eq("overridden")
92
94
  }
93
95
  end
94
96
 
95
- it "does not have have before or after callbacks by default" do
97
+ it "does not have have before callbacks by default" do
96
98
  expect(Bugsnag.before_notify_callbacks.size).to eq(0)
97
- expect(Bugsnag.after_notify_callbacks.size).to eq(0)
98
99
  Bugsnag.notify(BugsnagTestException.new("It crashed"))
99
100
  expect(Bugsnag).to have_sent_notification{ |payload|
100
101
  event = get_event_from_payload(payload)
@@ -102,18 +103,6 @@ describe Bugsnag::MiddlewareStack do
102
103
  }
103
104
  end
104
105
 
105
- it "runs after_bugsnag_notify callbacks" do
106
- callback_run_count = 0
107
- Bugsnag.after_notify_callbacks << lambda {|notif|
108
- callback_run_count += 1
109
- }
110
-
111
- Bugsnag.notify(BugsnagTestException.new("It crashed"))
112
-
113
- expect(callback_run_count).to eq(1)
114
- expect(Bugsnag::Notification).to have_sent_notification { }
115
- end
116
-
117
106
  it "does not execute disabled bugsnag middleware" do
118
107
  callback_run_count = 0
119
108
  Bugsnag.configure do |config|
@@ -133,7 +122,7 @@ describe Bugsnag::MiddlewareStack do
133
122
  notif.ignore!
134
123
  end
135
124
  Bugsnag.notify(BugsnagTestException.new("It crashed"))
136
- expect(Bugsnag::Notification).not_to have_sent_notification { }
125
+ expect(Bugsnag).not_to have_sent_notification
137
126
  end
138
127
 
139
128
  it "allows inspection of meta_data before ignoring exception" do
@@ -148,34 +137,118 @@ describe Bugsnag::MiddlewareStack do
148
137
  end
149
138
 
150
139
  Bugsnag.notify(BugsnagTestException.new("It crashed"))
151
- expect(Bugsnag::Notification).not_to have_sent_notification
140
+ expect(Bugsnag).not_to have_sent_notification
152
141
 
153
142
  end
154
143
 
155
144
  it "allows meta_data to be modified in a middleware" do
145
+ MetaDataAdder = Class.new do
146
+ def initialize(bugsnag)
147
+ @bugsnag = bugsnag
148
+ end
149
+
150
+ def call(report)
151
+ report.meta_data = {test: {value: "abcdef123456abcdef123456abcdef123456"}}
152
+ @bugsnag.call(report)
153
+ end
154
+ end
155
+
156
156
  MetaDataMunger = Class.new do
157
157
  def initialize(bugsnag)
158
158
  @bugsnag = bugsnag
159
159
  end
160
160
 
161
- def call(notification)
162
- token = notification.meta_data[:sidekiq][:args].first
163
- notification.meta_data[:sidekiq][:args] = ["#{token[0...6]}*****#{token[-4..-1]}"]
164
- @bugsnag.call(notification)
161
+ def call(report)
162
+ token = report.meta_data[:test][:value]
163
+ report.meta_data[:test][:value] = "#{token[0...6]}*****#{token[-4..-1]}"
164
+ @bugsnag.call(report)
165
165
  end
166
166
  end
167
167
 
168
168
  Bugsnag.configure do |c|
169
+ c.middleware.use MetaDataAdder
169
170
  c.middleware.use MetaDataMunger
170
171
  end
171
172
 
172
- notification = Bugsnag.notify(BugsnagTestException.new("It crashed"), {
173
- :sidekiq => {
174
- :args => ["abcdef123456abcdef123456abcdef123456"]
175
- }
176
- })
173
+ Bugsnag.notify(BugsnagTestException.new("It crashed"))
174
+
175
+ expect(Bugsnag).to have_sent_notification{ |payload|
176
+ event = get_event_from_payload(payload)
177
+ expect(event["metaData"]['test']['value']).to eq("abcdef*****3456")
178
+ }
179
+ end
177
180
 
178
- expect(notification.meta_data[:sidekiq][:args]).to eq(["abcdef*****3456"])
181
+ if ruby_version_greater_equal?("2.3.0")
182
+ context "with a ruby version >= 2.3.0" do
183
+ it "attaches did you mean metadata when necessary" do
184
+ begin
185
+ "Test".prepnd "T"
186
+ rescue Exception => e
187
+ Bugsnag.notify(e)
188
+ end
189
+
190
+ expect(Bugsnag).to have_sent_notification{ |payload|
191
+ event = get_event_from_payload(payload)
192
+ expect(event["metaData"]["error"]).to_not be_nil
193
+ expect(event["metaData"]["error"]).to eq({"suggestion" => "prepend"})
194
+ }
195
+ end
196
+ end
197
+ end
198
+
199
+ context "with a ruby version < 2.3.0" do
200
+ if !ruby_version_greater_equal?("2.3.0")
201
+ it "doesn't attach did you mean metadata" do
202
+ begin
203
+ "Test".prepnd "T"
204
+ rescue Exception => e
205
+ Bugsnag.notify(e)
206
+ end
207
+
208
+ expect(Bugsnag).to have_sent_notification{ |payload|
209
+ event = get_event_from_payload(payload)
210
+ expect(event["metaData"]["error"]).to be_nil
211
+ }
212
+ end
213
+ end
179
214
  end
180
215
 
216
+ it "doesn't allow handledState properties to be changed in middleware" do
217
+ HandledStateChanger = Class.new do
218
+ def initialize(bugsnag)
219
+ @bugsnag = bugsnag
220
+ end
221
+
222
+ def call(report)
223
+ report.severity_reason = {
224
+ :test => "test"
225
+ }
226
+ @bugsnag.call(report)
227
+ end
228
+ end
229
+
230
+ Bugsnag.configure do |c|
231
+ c.middleware.use HandledStateChanger
232
+ end
233
+
234
+ Bugsnag.notify(BugsnagTestException.new("It crashed"), true) do |report|
235
+ report.severity_reason = {
236
+ :type => "middleware_handler",
237
+ :attributes => {
238
+ :name => "middleware_test"
239
+ }
240
+ }
241
+ end
242
+
243
+ expect(Bugsnag).to have_sent_notification{ |payload|
244
+ event = get_event_from_payload(payload)
245
+ expect(event["unhandled"]).to be true
246
+ expect(event["severityReason"]).to eq({
247
+ "type" => "middleware_handler",
248
+ "attributes" => {
249
+ "name" => "middleware_test"
250
+ }
251
+ })
252
+ }
253
+ end
181
254
  end
@@ -54,7 +54,7 @@ describe Bugsnag::Rack do
54
54
 
55
55
  rack_stack.call(rack_env) rescue nil
56
56
 
57
- expect(Bugsnag::Notification).not_to have_sent_notification
57
+ expect(Bugsnag).not_to have_sent_notification
58
58
  end
59
59
  end
60
60
 
@@ -27,7 +27,7 @@ class JRubyException
27
27
  end
28
28
  end
29
29
 
30
- describe Bugsnag::Notification do
30
+ describe Bugsnag::Report do
31
31
  it "should contain an api_key if one is set" do
32
32
  Bugsnag.notify(BugsnagTestException.new("It crashed"))
33
33
 
@@ -53,7 +53,9 @@ describe Bugsnag::Notification do
53
53
  end
54
54
 
55
55
  it "lets you override the api_key" do
56
- Bugsnag.notify(BugsnagTestException.new("It crashed"), :api_key => "9d84383f9be2ca94902e45c756a9979d")
56
+ Bugsnag.notify(BugsnagTestException.new("It crashed")) do |report|
57
+ report.api_key = "9d84383f9be2ca94902e45c756a9979d"
58
+ end
57
59
 
58
60
  expect(Bugsnag).to have_sent_notification{ |payload|
59
61
  expect(payload["apiKey"]).to eq("9d84383f9be2ca94902e45c756a9979d")
@@ -62,7 +64,9 @@ describe Bugsnag::Notification do
62
64
 
63
65
  it "lets you override the groupingHash" do
64
66
 
65
- Bugsnag.notify(BugsnagTestException.new("It crashed"), {:grouping_hash => "this is my grouping hash"})
67
+ Bugsnag.notify(BugsnagTestException.new("It crashed")) do |report|
68
+ report.grouping_hash = "this is my grouping hash"
69
+ end
66
70
 
67
71
  expect(Bugsnag).to have_sent_notification{ |payload|
68
72
  event = get_event_from_payload(payload)
@@ -115,7 +119,7 @@ describe Bugsnag::Notification do
115
119
 
116
120
  it "uses correct unhandled defaults" do
117
121
  Bugsnag.notify(BugsnagTestException.new("It crashed"))
118
-
122
+
119
123
  expect(Bugsnag).to have_sent_notification{ |payload|
120
124
  event = get_event_from_payload(payload)
121
125
  expect(event["unhandled"]).to be false
@@ -126,19 +130,6 @@ describe Bugsnag::Notification do
126
130
  }
127
131
  end
128
132
 
129
- it "sets correct severityReason if severity is modified" do
130
- Bugsnag.notify(BugsnagTestException.new("It crashed"), {:severity => "info"})
131
-
132
- expect(Bugsnag).to have_sent_notification{ |payload|
133
- event = get_event_from_payload(payload)
134
- expect(event["unhandled"]).to be false
135
- expect(event["severity"]).to eq("info")
136
- expect(event["severityReason"]).to eq({
137
- "type" => "userSpecifiedSeverity"
138
- })
139
- }
140
- end
141
-
142
133
  it "sets correct severityReason if severity is modified in a block" do
143
134
  Bugsnag.notify(BugsnagTestException.new("It crashed")) do |notification|
144
135
  notification.severity = "info"
@@ -153,28 +144,6 @@ describe Bugsnag::Notification do
153
144
  }
154
145
  end
155
146
 
156
- it "sets unhandled and severityReasons through auto_notify" do
157
- Bugsnag.auto_notify(BugsnagTestException.new("It crashed"), {
158
- :severity_reason => {
159
- :type => "unhandledExceptionMiddleware",
160
- :attributes => {
161
- :framework => "ruby test"
162
- }
163
- }
164
- })
165
- expect(Bugsnag).to have_sent_notification{ |payload|
166
- event = get_event_from_payload(payload)
167
- expect(event["unhandled"]).to be true
168
- expect(event["severity"]).to eq("error")
169
- expect(event["severityReason"]).to eq({
170
- "type" => "unhandledExceptionMiddleware",
171
- "attributes" => {
172
- "framework" => "ruby test"
173
- }
174
- })
175
- }
176
- end
177
-
178
147
  it "sets correct severity and reason for specific error classes" do
179
148
  Bugsnag.notify(SignalException.new("TERM"))
180
149
  expect(Bugsnag).to have_sent_notification{ |payload|
@@ -193,12 +162,14 @@ describe Bugsnag::Notification do
193
162
  # TODO: nested context
194
163
 
195
164
  it "accepts tabs in overrides and adds them to metaData" do
196
- Bugsnag.notify(BugsnagTestException.new("It crashed"), {
197
- :some_tab => {
198
- :info => "here",
199
- :data => "also here"
200
- }
201
- })
165
+ Bugsnag.notify(BugsnagTestException.new("It crashed")) do |report|
166
+ report.meta_data.merge!({
167
+ some_tab: {
168
+ info: "here",
169
+ data: "also here"
170
+ }
171
+ })
172
+ end
202
173
 
203
174
  expect(Bugsnag).to have_sent_notification{ |payload|
204
175
  event = get_event_from_payload(payload)
@@ -209,22 +180,27 @@ describe Bugsnag::Notification do
209
180
  }
210
181
  end
211
182
 
212
- it "accepts non-hash overrides and adds them to the custom tab in metaData" do
213
- Bugsnag.notify(BugsnagTestException.new("It crashed"), {
214
- :info => "here",
215
- :data => "also here"
216
- })
183
+ it "accepts meta data from an exception that mixes in Bugsnag::MetaData" do
184
+ exception = BugsnagTestExceptionWithMetaData.new("It crashed")
185
+ exception.bugsnag_meta_data = {
186
+ some_tab: {
187
+ info: "here",
188
+ data: "also here"
189
+ }
190
+ }
191
+
192
+ Bugsnag.notify(exception)
217
193
 
218
194
  expect(Bugsnag).to have_sent_notification{ |payload|
219
195
  event = get_event_from_payload(payload)
220
- expect(event["metaData"]["custom"]).to eq(
196
+ expect(event["metaData"]["some_tab"]).to eq(
221
197
  "info" => "here",
222
198
  "data" => "also here"
223
199
  )
224
200
  }
225
201
  end
226
202
 
227
- it "accepts meta data from an exception that mixes in Bugsnag::MetaData" do
203
+ it "removes tabs" do
228
204
  exception = BugsnagTestExceptionWithMetaData.new("It crashed")
229
205
  exception.bugsnag_meta_data = {
230
206
  :some_tab => {
@@ -233,7 +209,28 @@ describe Bugsnag::Notification do
233
209
  }
234
210
  }
235
211
 
236
- Bugsnag.notify(exception)
212
+ Bugsnag.notify(exception) do |report|
213
+ report.remove_tab(:some_tab)
214
+ end
215
+
216
+ expect(Bugsnag).to have_sent_notification{ |payload|
217
+ event = get_event_from_payload(payload)
218
+ expect(event["metaData"]["some_tab"]).to be_nil
219
+ }
220
+ end
221
+
222
+ it "ignores removing nil tabs" do
223
+ exception = BugsnagTestExceptionWithMetaData.new("It crashed")
224
+ exception.bugsnag_meta_data = {
225
+ :some_tab => {
226
+ :info => "here",
227
+ :data => "also here"
228
+ }
229
+ }
230
+
231
+ Bugsnag.notify(exception) do |report|
232
+ report.remove_tab(nil)
233
+ end
237
234
 
238
235
  expect(Bugsnag).to have_sent_notification{ |payload|
239
236
  event = get_event_from_payload(payload)
@@ -244,6 +241,21 @@ describe Bugsnag::Notification do
244
241
  }
245
242
  end
246
243
 
244
+ it "Creates a custom tab for metadata which is not a Hash" do
245
+ exception = Exception.new("It crashed")
246
+
247
+ Bugsnag.notify(exception) do |report|
248
+ report.add_tab(:some_tab, "added")
249
+ end
250
+
251
+ expect(Bugsnag).to have_sent_notification{ |payload|
252
+ event = get_event_from_payload(payload)
253
+ expect(event["metaData"]["custom"]).to eq(
254
+ "some_tab" => "added",
255
+ )
256
+ }
257
+ end
258
+
247
259
  it "accepts meta data from an exception that mixes in Bugsnag::MetaData, but override using the overrides" do
248
260
  exception = BugsnagTestExceptionWithMetaData.new("It crashed")
249
261
  exception.bugsnag_meta_data = {
@@ -253,7 +265,9 @@ describe Bugsnag::Notification do
253
265
  }
254
266
  }
255
267
 
256
- Bugsnag.notify(exception, {:some_tab => {:info => "overridden"}})
268
+ Bugsnag.notify(exception) do |report|
269
+ report.add_tab(:some_tab, {:info => "overridden"})
270
+ end
257
271
 
258
272
  expect(Bugsnag).to have_sent_notification{ |payload|
259
273
  event = get_event_from_payload(payload)
@@ -280,7 +294,9 @@ describe Bugsnag::Notification do
280
294
  exception = BugsnagTestExceptionWithMetaData.new("It crashed")
281
295
  exception.bugsnag_user_id = "exception_user_id"
282
296
 
283
- Bugsnag.notify(exception, {:user_id => "override_user_id"})
297
+ Bugsnag.notify(exception) do |report|
298
+ report.user.merge!({:id => "override_user_id"})
299
+ end
284
300
 
285
301
  expect(Bugsnag).to have_sent_notification{ |payload|
286
302
  event = get_event_from_payload(payload)
@@ -317,7 +333,9 @@ describe Bugsnag::Notification do
317
333
  exception = BugsnagTestExceptionWithMetaData.new("It crashed")
318
334
  exception.bugsnag_context = "exception_context"
319
335
 
320
- Bugsnag.notify(exception, {:context => "override_context"})
336
+ Bugsnag.notify(exception) do |report|
337
+ report.context = "override_context"
338
+ end
321
339
 
322
340
  expect(Bugsnag).to have_sent_notification{ |payload|
323
341
  event = get_event_from_payload(payload)
@@ -326,14 +344,14 @@ describe Bugsnag::Notification do
326
344
  end
327
345
 
328
346
  it "accepts meta_data in overrides (for backwards compatibility) and merge it into metaData" do
329
- Bugsnag.notify(BugsnagTestException.new("It crashed"), {
330
- :meta_data => {
331
- :some_tab => {
332
- :info => "here",
333
- :data => "also here"
347
+ Bugsnag.notify(BugsnagTestException.new("It crashed")) do |report|
348
+ report.meta_data.merge!({
349
+ some_tab: {
350
+ info: "here",
351
+ data: "also here"
334
352
  }
335
- }
336
- })
353
+ })
354
+ end
337
355
 
338
356
  expect(Bugsnag).to have_sent_notification{ |payload|
339
357
  event = get_event_from_payload(payload)
@@ -345,14 +363,14 @@ describe Bugsnag::Notification do
345
363
  end
346
364
 
347
365
  it "truncates large meta_data before sending" do
348
- Bugsnag.notify(BugsnagTestException.new("It crashed"), {
349
- :meta_data => {
350
- :some_tab => {
351
- :giant => SecureRandom.hex(500_000/2),
352
- :mega => SecureRandom.hex(500_000/2)
366
+ Bugsnag.notify(BugsnagTestException.new("It crashed")) do |report|
367
+ report.meta_data.merge!({
368
+ some_tab: {
369
+ giant: SecureRandom.hex(500_000/2),
370
+ mega: SecureRandom.hex(500_000/2)
353
371
  }
354
- }
355
- })
372
+ })
373
+ end
356
374
 
357
375
  expect(Bugsnag).to have_sent_notification{ |payload|
358
376
  # Truncated body should be no bigger than
@@ -362,14 +380,14 @@ describe Bugsnag::Notification do
362
380
  end
363
381
 
364
382
  it "truncates large messages before sending" do
365
- Bugsnag.notify(BugsnagTestException.new(SecureRandom.hex(500_000)), {
366
- :meta_data => {
367
- :some_tab => {
368
- :giant => SecureRandom.hex(500_000/2),
369
- :mega => SecureRandom.hex(500_000/2)
383
+ Bugsnag.notify(BugsnagTestException.new(SecureRandom.hex(500_000))) do |report|
384
+ report.meta_data.merge!({
385
+ some_tab: {
386
+ giant: SecureRandom.hex(500_000/2),
387
+ mega: SecureRandom.hex(500_000/2)
370
388
  }
371
- }
372
- })
389
+ })
390
+ end
373
391
 
374
392
  expect(Bugsnag).to have_sent_notification{ |payload|
375
393
  # Truncated body should be no bigger than
@@ -393,9 +411,9 @@ describe Bugsnag::Notification do
393
411
  end
394
412
 
395
413
  it "accepts a severity in overrides" do
396
- Bugsnag.notify(BugsnagTestException.new("It crashed"), {
397
- :severity => "info"
398
- })
414
+ Bugsnag.notify(BugsnagTestException.new("It crashed")) do |report|
415
+ report.severity = "info"
416
+ end
399
417
 
400
418
  expect(Bugsnag).to have_sent_notification{ |payload|
401
419
  event = get_event_from_payload(payload)
@@ -413,42 +431,10 @@ describe Bugsnag::Notification do
413
431
  }
414
432
  end
415
433
 
416
- it "does not accept a bad severity in overrides" do
417
- Bugsnag.notify(BugsnagTestException.new("It crashed"), {
418
- :severity => "fatal"
419
- })
420
-
421
- expect(Bugsnag).to have_sent_notification{ |payload|
422
- event = get_event_from_payload(payload)
423
- expect(event["severity"]).to eq("warning")
424
- }
425
- end
426
-
427
- it "lets you override severity using block syntax" do
428
- Bugsnag.notify(BugsnagTestException.new("It crashed")) do |notification|
429
- notification.severity = "info"
430
- end
431
-
432
- expect(Bugsnag).to have_sent_notification{ |payload|
433
- event = get_event_from_payload(payload)
434
- expect(event["severity"]).to eq("info")
435
- }
436
- end
437
-
438
- it "autonotifies errors" do
439
- Bugsnag.auto_notify(BugsnagTestException.new("It crashed"))
440
-
441
- expect(Bugsnag).to have_sent_notification{ |payload|
442
- event = get_event_from_payload(payload)
443
- expect(event["severity"]).to eq("error")
444
- }
445
- end
446
-
447
-
448
434
  it "accepts a context in overrides" do
449
- Bugsnag.notify(BugsnagTestException.new("It crashed"), {
450
- :context => "test_context"
451
- })
435
+ Bugsnag.notify(BugsnagTestException.new("It crashed")) do |report|
436
+ report.context = 'test_context'
437
+ end
452
438
 
453
439
  expect(Bugsnag).to have_sent_notification{ |payload|
454
440
  event = get_event_from_payload(payload)
@@ -457,9 +443,9 @@ describe Bugsnag::Notification do
457
443
  end
458
444
 
459
445
  it "accepts a user_id in overrides" do
460
- Bugsnag.notify(BugsnagTestException.new("It crashed"), {
461
- :user_id => "test_user"
462
- })
446
+ Bugsnag.notify(BugsnagTestException.new("It crashed")) do |report|
447
+ report.user = {id: 'test_user'}
448
+ end
463
449
 
464
450
  expect(Bugsnag).to have_sent_notification{ |payload|
465
451
  event = get_event_from_payload(payload)
@@ -467,12 +453,12 @@ describe Bugsnag::Notification do
467
453
  }
468
454
  end
469
455
 
470
- it "does not send a notification if auto_notify is false" do
456
+ it "does not send an automatic notification if auto_notify is false" do
471
457
  Bugsnag.configure do |config|
472
458
  config.auto_notify = false
473
459
  end
474
460
 
475
- Bugsnag.auto_notify(BugsnagTestException.new("It crashed"))
461
+ Bugsnag.notify(BugsnagTestException.new("It crashed"), true)
476
462
 
477
463
  expect(Bugsnag).not_to have_sent_notification
478
464
  end
@@ -482,7 +468,7 @@ describe Bugsnag::Notification do
482
468
  config.release_stage = "production"
483
469
  end
484
470
 
485
- Bugsnag.auto_notify(BugsnagTestException.new("It crashed"))
471
+ Bugsnag.notify(BugsnagTestException.new("It crashed"))
486
472
 
487
473
  expect(Bugsnag).to have_sent_notification{ |payload|
488
474
  event = get_event_from_payload(payload)
@@ -516,27 +502,6 @@ describe Bugsnag::Notification do
516
502
  expect(WebMock).to have_requested(:post, "https://notify.bugsnag.com")
517
503
  end
518
504
 
519
- it "uses ssl when use_ssl is true" do
520
- Bugsnag.configuration.use_ssl = true
521
- Bugsnag.notify(BugsnagTestException.new("It crashed"))
522
-
523
- expect(WebMock).to have_requested(:post, "https://notify.bugsnag.com")
524
- end
525
-
526
- it "does not use ssl when use_ssl is false" do
527
- stub_request(:post, "http://notify.bugsnag.com/")
528
- Bugsnag.configuration.use_ssl = false
529
- Bugsnag.notify(BugsnagTestException.new("It crashed"))
530
-
531
- expect(WebMock).to have_requested(:post, "http://notify.bugsnag.com")
532
- end
533
-
534
- it "uses ssl when use_ssl is unset" do
535
- Bugsnag.notify(BugsnagTestException.new("It crashed"))
536
-
537
- expect(WebMock).to have_requested(:post, "https://notify.bugsnag.com")
538
- end
539
-
540
505
  it "does not mark the top-most stacktrace line as inProject if out of project" do
541
506
  Bugsnag.configuration.project_root = "/Random/location/here"
542
507
  Bugsnag.notify(BugsnagTestException.new("It crashed"))
@@ -548,19 +513,6 @@ describe Bugsnag::Notification do
548
513
  }
549
514
  end
550
515
 
551
- it "does not mark the top-most stacktrace line as inProject if it matches a vendor path" do
552
- Bugsnag.configuration.project_root = File.expand_path('../../', __FILE__)
553
- Bugsnag.configuration.vendor_paths = [File.expand_path('../', __FILE__)]
554
-
555
- Bugsnag.notify(BugsnagTestException.new("It crashed"))
556
-
557
- expect(Bugsnag).to have_sent_notification{ |payload|
558
- exception = get_exception_from_payload(payload)
559
- expect(exception["stacktrace"].size).to be >= 1
560
- expect(exception["stacktrace"].first["inProject"]).to be_nil
561
- }
562
- end
563
-
564
516
  it "marks the top-most stacktrace line as inProject if necessary" do
565
517
  Bugsnag.configuration.project_root = File.expand_path File.dirname(__FILE__)
566
518
  Bugsnag.notify(BugsnagTestException.new("It crashed"))
@@ -582,9 +534,11 @@ describe Bugsnag::Notification do
582
534
  }
583
535
  end
584
536
 
585
- it "filters params from all payload hashes if they are set in default params_filters" do
537
+ it "filters params from all payload hashes if they are set in default meta_data_filters" do
586
538
 
587
- Bugsnag.notify(BugsnagTestException.new("It crashed"), {:request => {:params => {:password => "1234", :other_password => "12345", :other_data => "123456"}}})
539
+ Bugsnag.notify(BugsnagTestException.new("It crashed")) do |report|
540
+ report.meta_data.merge!({:request => {:params => {:password => "1234", :other_password => "12345", :other_data => "123456"}}})
541
+ end
588
542
 
589
543
  expect(Bugsnag).to have_sent_notification{ |payload|
590
544
  event = get_event_from_payload(payload)
@@ -597,10 +551,12 @@ describe Bugsnag::Notification do
597
551
  }
598
552
  end
599
553
 
600
- it "filters params from all payload hashes if they are added to params_filters" do
554
+ it "filters params from all payload hashes if they are added to meta_data_filters" do
601
555
 
602
- Bugsnag.configuration.params_filters << "other_data"
603
- Bugsnag.notify(BugsnagTestException.new("It crashed"), {:request => {:params => {:password => "1234", :other_password => "123456", :other_data => "123456"}}})
556
+ Bugsnag.configuration.meta_data_filters << "other_data"
557
+ Bugsnag.notify(BugsnagTestException.new("It crashed")) do |report|
558
+ report.meta_data.merge!({:request => {:params => {:password => "1234", :other_password => "123456", :other_data => "123456"}}})
559
+ end
604
560
 
605
561
  expect(Bugsnag).to have_sent_notification{ |payload|
606
562
  event = get_event_from_payload(payload)
@@ -613,10 +569,12 @@ describe Bugsnag::Notification do
613
569
  }
614
570
  end
615
571
 
616
- it "filters params from all payload hashes if they are added to params_filters as regex" do
572
+ it "filters params from all payload hashes if they are added to meta_data_filters as regex" do
617
573
 
618
- Bugsnag.configuration.params_filters << /other_data/
619
- Bugsnag.notify(BugsnagTestException.new("It crashed"), {:request => {:params => {:password => "1234", :other_password => "123456", :other_data => "123456"}}})
574
+ Bugsnag.configuration.meta_data_filters << /other_data/
575
+ Bugsnag.notify(BugsnagTestException.new("It crashed")) do |report|
576
+ report.meta_data.merge!({:request => {:params => {:password => "1234", :other_password => "123456", :other_data => "123456"}}})
577
+ end
620
578
 
621
579
  expect(Bugsnag).to have_sent_notification{ |payload|
622
580
  event = get_event_from_payload(payload)
@@ -629,10 +587,12 @@ describe Bugsnag::Notification do
629
587
  }
630
588
  end
631
589
 
632
- it "filters params from all payload hashes if they are added to params_filters as partial regex" do
590
+ it "filters params from all payload hashes if they are added to meta_data_filters as partial regex" do
633
591
 
634
- Bugsnag.configuration.params_filters << /r_data/
635
- Bugsnag.notify(BugsnagTestException.new("It crashed"), {:request => {:params => {:password => "1234", :other_password => "123456", :other_data => "123456"}}})
592
+ Bugsnag.configuration.meta_data_filters << /r_data/
593
+ Bugsnag.notify(BugsnagTestException.new("It crashed")) do |report|
594
+ report.meta_data.merge!({:request => {:params => {:password => "1234", :other_password => "123456", :other_data => "123456"}}})
595
+ end
636
596
 
637
597
  expect(Bugsnag).to have_sent_notification{ |payload|
638
598
  event = get_event_from_payload(payload)
@@ -646,7 +606,9 @@ describe Bugsnag::Notification do
646
606
  end
647
607
 
648
608
  it "does not filter params from payload hashes if their values are nil" do
649
- Bugsnag.notify(BugsnagTestException.new("It crashed"), {:request => {:params => {:nil_param => nil}}})
609
+ Bugsnag.notify(BugsnagTestException.new("It crashed")) do |report|
610
+ report.meta_data.merge!({:request => {:params => {:nil_param => nil}}})
611
+ end
650
612
 
651
613
  expect(Bugsnag).to have_sent_notification{ |payload|
652
614
  event = get_event_from_payload(payload)
@@ -657,49 +619,46 @@ describe Bugsnag::Notification do
657
619
  }
658
620
  end
659
621
 
660
- it "does not notify if the non-default exception class is added to the ignore_classes" do
661
- Bugsnag.configuration.ignore_classes << "BugsnagTestException"
662
-
663
- Bugsnag.notify_or_ignore(BugsnagTestException.new("It crashed"))
622
+ it "does not notify if report ignored" do
623
+ Bugsnag.notify(BugsnagTestException.new("It crashed")) do |report|
624
+ report.ignore!
625
+ end
664
626
 
665
627
  expect(Bugsnag).not_to have_sent_notification
666
628
  end
667
629
 
668
- it "does not notify if exception's ancestor is an ignored class" do
669
- Bugsnag.configuration.ignore_classes << "BugsnagTestException"
670
-
671
- Bugsnag.notify_or_ignore(BugsnagSubclassTestException.new("It crashed"))
630
+ it "does not notify if the exception class is in the default ignore_classes list" do
631
+ Bugsnag.configuration.ignore_classes << ActiveRecord::RecordNotFound
632
+ Bugsnag.notify(ActiveRecord::RecordNotFound.new("It crashed"))
672
633
 
673
634
  expect(Bugsnag).not_to have_sent_notification
674
635
  end
675
636
 
676
- it "does not notify if any caused exception is an ignored class" do
677
- Bugsnag.configuration.ignore_classes << "NestedException"
678
-
679
- ex = NestedException.new("Self-referential exception")
680
- ex.original_exception = BugsnagTestException.new("It crashed")
637
+ it "does not notify if the non-default exception class is added to the ignore_classes" do
638
+ Bugsnag.configuration.ignore_classes << BugsnagTestException
681
639
 
682
- Bugsnag.notify_or_ignore(ex)
640
+ Bugsnag.notify(BugsnagTestException.new("It crashed"))
683
641
 
684
642
  expect(Bugsnag).not_to have_sent_notification
685
643
  end
686
644
 
687
- it "accepts both String and Class instances as an ignored class" do
645
+ it "does not notify if exception's ancestor is an ignored class" do
688
646
  Bugsnag.configuration.ignore_classes << BugsnagTestException
689
647
 
690
- Bugsnag.notify_or_ignore(BugsnagTestException.new("It crashed"))
648
+ Bugsnag.notify(BugsnagSubclassTestException.new("It crashed"))
691
649
 
692
650
  expect(Bugsnag).not_to have_sent_notification
693
651
  end
694
652
 
695
- it "does not notify if the user agent is present and matches a regex in ignore_user_agents" do
696
- Bugsnag.configuration.ignore_user_agents << %r{BugsnagUserAgent}
653
+ it "does not notify if any caused exception is an ignored class" do
654
+ Bugsnag.configuration.ignore_classes << NestedException
697
655
 
698
- ((Thread.current["bugsnag_req_data"] ||= {})[:rack_env] ||= {})["HTTP_USER_AGENT"] = "BugsnagUserAgent"
656
+ ex = NestedException.new("Self-referential exception")
657
+ ex.original_exception = BugsnagTestException.new("It crashed")
699
658
 
700
- Bugsnag.notify_or_ignore(BugsnagTestException.new("It crashed"))
659
+ Bugsnag.notify(ex)
701
660
 
702
- expect(Bugsnag::Notification).not_to have_sent_notification
661
+ expect(Bugsnag).not_to have_sent_notification
703
662
  end
704
663
 
705
664
  it "sends the cause of the exception" do
@@ -723,7 +682,7 @@ describe Bugsnag::Notification do
723
682
  ex = NestedException.new("Self-referential exception")
724
683
  ex.original_exception = ex
725
684
 
726
- Bugsnag.notify_or_ignore(ex)
685
+ Bugsnag.notify(ex)
727
686
 
728
687
  expect(Bugsnag).to have_sent_notification{ |payload|
729
688
  event = get_event_from_payload(payload)
@@ -738,7 +697,7 @@ describe Bugsnag::Notification do
738
697
  ex = ex.original_exception = NestedException.new("Deep exception #{idx}")
739
698
  end
740
699
 
741
- Bugsnag.notify_or_ignore(first_ex)
700
+ Bugsnag.notify(first_ex)
742
701
  expect(Bugsnag).to have_sent_notification{ |payload|
743
702
  event = get_event_from_payload(payload)
744
703
  expect(event["exceptions"].size).to eq(5)
@@ -819,34 +778,39 @@ describe Bugsnag::Notification do
819
778
  invalid_data = "fl\xc3ff"
820
779
  invalid_data.force_encoding('BINARY') if invalid_data.respond_to?(:force_encoding)
821
780
 
822
- notify_test_exception(:fluff => {:fluff => invalid_data})
781
+ Bugsnag.notify(BugsnagTestException.new("It crashed")) do |report|
782
+ report.meta_data.merge!({fluff: {fluff: invalid_data}})
783
+ end
823
784
 
824
785
  expect(Bugsnag).to have_sent_notification{ |payload|
786
+ event = get_event_from_payload(payload)
825
787
  if defined?(Encoding::UTF_8)
826
- expect(payload.to_json).to match(/fl�ff/)
788
+ expect(event['metaData']['fluff']['fluff']).to match(/fl�ff/)
827
789
  else
828
- expect(payload.to_json).to match(/flff/)
790
+ expect(event['metaData']['fluff']['fluff']).to match(/flff/)
829
791
  end
830
792
  }
831
793
  end
832
794
 
833
- it "should handle utf8 encoding errors in exceptions_list" do
834
- invalid_data = "\"foo\xEBbar\""
835
- invalid_data = invalid_data.force_encoding("utf-8") if invalid_data.respond_to?(:force_encoding)
795
+ if RUBY_VERSION < '2.3.0'
796
+ it "should handle utf8 encoding errors in exceptions_list" do
797
+ invalid_data = "\"foo\xEBbar\""
798
+ invalid_data = invalid_data.force_encoding("utf-8") if invalid_data.respond_to?(:force_encoding)
836
799
 
837
- begin
838
- JSON.parse(invalid_data)
839
- rescue
840
- Bugsnag.notify $!
841
- end
842
-
843
- expect(Bugsnag).to have_sent_notification { |payload|
844
- if defined?(Encoding::UTF_8)
845
- expect(payload.to_json).to match(/foo�bar/)
846
- else
847
- expect(payload.to_json).to match(/foobar/)
800
+ begin
801
+ JSON.parse(invalid_data)
802
+ rescue
803
+ Bugsnag.notify $!
848
804
  end
849
- }
805
+
806
+ expect(Bugsnag).to have_sent_notification { |payload|
807
+ if defined?(Encoding::UTF_8)
808
+ expect(payload.to_json).to match(/foo�bar/)
809
+ else
810
+ expect(payload.to_json).to match(/foobar/)
811
+ end
812
+ }
813
+ end
850
814
  end
851
815
 
852
816
  it "should handle utf8 encoding errors in notification context" do
@@ -856,7 +820,9 @@ describe Bugsnag::Notification do
856
820
  begin
857
821
  raise
858
822
  rescue
859
- Bugsnag.notify($!, { :context => invalid_data })
823
+ Bugsnag.notify($!) do |report|
824
+ report.context = invalid_data
825
+ end
860
826
  end
861
827
 
862
828
  expect(Bugsnag).to have_sent_notification { |payload|
@@ -955,6 +921,57 @@ describe Bugsnag::Notification do
955
921
  }
956
922
  end
957
923
 
924
+ it 'should use defaults when notify is called' do
925
+ Bugsnag.notify(BugsnagTestException.new("It crashed"))
926
+
927
+ expect(Bugsnag).to have_sent_notification{ |payload|
928
+ event = payload["events"][0]
929
+ expect(event["unhandled"]).to be false
930
+ expect(event["severityReason"]).to eq({"type" => "handledException"})
931
+ }
932
+ end
933
+
934
+ it 'should attach severity reason through a block when auto_notify is true' do
935
+ Bugsnag.notify(BugsnagTestException.new("It crashed"), true) do |report|
936
+ report.severity_reason = {
937
+ :type => "middleware_handler",
938
+ :attributes => {
939
+ :name => "middleware_test"
940
+ }
941
+ }
942
+ end
943
+
944
+ expect(Bugsnag).to have_sent_notification{ |payload|
945
+ event = payload["events"][0]
946
+ expect(event["severityReason"]).to eq(
947
+ {
948
+ "type" => "middleware_handler",
949
+ "attributes" => {
950
+ "name" => "middleware_test"
951
+ }
952
+ }
953
+ )
954
+ expect(event["unhandled"]).to be true
955
+ }
956
+ end
957
+
958
+ it 'should not attach severity reason from callback when auto_notify is false' do
959
+ Bugsnag.notify(BugsnagTestException.new("It crashed")) do |report|
960
+ report.severity_reason = {
961
+ :type => "middleware_handler",
962
+ :attributes => {
963
+ :name => "middleware_test"
964
+ }
965
+ }
966
+ end
967
+
968
+ expect(Bugsnag).to have_sent_notification{ |payload|
969
+ event = payload["events"][0]
970
+ expect(event["unhandled"]).to be false
971
+ expect(event["severityReason"]).to eq({"type" => "handledException"})
972
+ }
973
+ end
974
+
958
975
  if defined?(JRUBY_VERSION)
959
976
 
960
977
  it "should work with java.lang.Throwables" do