appsignal 3.9.2-java → 3.10.0-java

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (105) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +3138 -0
  3. data/.rubocop.yml +28 -20
  4. data/.rubocop_todo.yml +7 -33
  5. data/CHANGELOG.md +130 -0
  6. data/README.md +0 -1
  7. data/Rakefile +80 -65
  8. data/appsignal.gemspec +1 -1
  9. data/build_matrix.yml +112 -184
  10. data/ext/base.rb +1 -1
  11. data/gemfiles/hanami-2.1.gemfile +7 -0
  12. data/gemfiles/webmachine1.gemfile +5 -4
  13. data/lib/appsignal/cli/diagnose.rb +1 -1
  14. data/lib/appsignal/config.rb +5 -1
  15. data/lib/appsignal/demo.rb +0 -1
  16. data/lib/appsignal/environment.rb +11 -2
  17. data/lib/appsignal/extension/jruby.rb +1 -1
  18. data/lib/appsignal/helpers/instrumentation.rb +164 -2
  19. data/lib/appsignal/hooks/active_job.rb +1 -6
  20. data/lib/appsignal/integrations/grape.rb +19 -47
  21. data/lib/appsignal/integrations/hanami.rb +8 -7
  22. data/lib/appsignal/integrations/padrino.rb +51 -52
  23. data/lib/appsignal/integrations/railtie.rb +0 -3
  24. data/lib/appsignal/integrations/rake.rb +46 -12
  25. data/lib/appsignal/integrations/sidekiq.rb +1 -11
  26. data/lib/appsignal/integrations/sinatra.rb +0 -1
  27. data/lib/appsignal/integrations/webmachine.rb +15 -9
  28. data/lib/appsignal/probes/gvl.rb +24 -2
  29. data/lib/appsignal/probes/sidekiq.rb +1 -1
  30. data/lib/appsignal/probes.rb +1 -1
  31. data/lib/appsignal/rack/abstract_middleware.rb +104 -33
  32. data/lib/appsignal/rack/body_wrapper.rb +143 -0
  33. data/lib/appsignal/rack/event_handler.rb +12 -3
  34. data/lib/appsignal/rack/generic_instrumentation.rb +5 -4
  35. data/lib/appsignal/rack/grape_middleware.rb +40 -0
  36. data/lib/appsignal/rack/hanami_middleware.rb +2 -12
  37. data/lib/appsignal/rack/instrumentation_middleware.rb +62 -0
  38. data/lib/appsignal/rack/rails_instrumentation.rb +14 -57
  39. data/lib/appsignal/rack/sinatra_instrumentation.rb +1 -3
  40. data/lib/appsignal/rack/streaming_listener.rb +13 -59
  41. data/lib/appsignal/rack.rb +31 -0
  42. data/lib/appsignal/transaction.rb +50 -8
  43. data/lib/appsignal/utils/integration_memory_logger.rb +78 -0
  44. data/lib/appsignal/utils.rb +1 -0
  45. data/lib/appsignal/version.rb +1 -1
  46. data/lib/appsignal.rb +36 -33
  47. data/spec/.rubocop.yml +1 -1
  48. data/spec/lib/appsignal/cli/diagnose_spec.rb +1 -1
  49. data/spec/lib/appsignal/cli/install_spec.rb +3 -3
  50. data/spec/lib/appsignal/config_spec.rb +8 -5
  51. data/spec/lib/appsignal/demo_spec.rb +38 -41
  52. data/spec/lib/appsignal/hooks/action_cable_spec.rb +86 -167
  53. data/spec/lib/appsignal/hooks/active_support_notifications/finish_with_state_shared_examples.rb +8 -20
  54. data/spec/lib/appsignal/hooks/active_support_notifications/instrument_shared_examples.rb +38 -84
  55. data/spec/lib/appsignal/hooks/active_support_notifications/start_finish_shared_examples.rb +16 -37
  56. data/spec/lib/appsignal/hooks/active_support_notifications_spec.rb +4 -4
  57. data/spec/lib/appsignal/hooks/activejob_spec.rb +111 -200
  58. data/spec/lib/appsignal/hooks/delayed_job_spec.rb +54 -91
  59. data/spec/lib/appsignal/hooks/dry_monitor_spec.rb +14 -32
  60. data/spec/lib/appsignal/hooks/excon_spec.rb +8 -12
  61. data/spec/lib/appsignal/hooks/net_http_spec.rb +7 -42
  62. data/spec/lib/appsignal/hooks/rake_spec.rb +107 -34
  63. data/spec/lib/appsignal/hooks/redis_client_spec.rb +18 -30
  64. data/spec/lib/appsignal/hooks/redis_spec.rb +10 -16
  65. data/spec/lib/appsignal/hooks/resque_spec.rb +42 -62
  66. data/spec/lib/appsignal/hooks/shoryuken_spec.rb +33 -74
  67. data/spec/lib/appsignal/integrations/hanami_spec.rb +79 -21
  68. data/spec/lib/appsignal/integrations/http_spec.rb +12 -20
  69. data/spec/lib/appsignal/integrations/net_http_spec.rb +33 -0
  70. data/spec/lib/appsignal/integrations/object_spec.rb +29 -36
  71. data/spec/lib/appsignal/integrations/padrino_spec.rb +190 -163
  72. data/spec/lib/appsignal/integrations/que_spec.rb +43 -70
  73. data/spec/lib/appsignal/integrations/railtie_spec.rb +26 -67
  74. data/spec/lib/appsignal/integrations/sidekiq_spec.rb +86 -160
  75. data/spec/lib/appsignal/integrations/sinatra_spec.rb +10 -3
  76. data/spec/lib/appsignal/integrations/webmachine_spec.rb +77 -40
  77. data/spec/lib/appsignal/probes/gvl_spec.rb +80 -3
  78. data/spec/lib/appsignal/probes_spec.rb +7 -4
  79. data/spec/lib/appsignal/rack/abstract_middleware_spec.rb +302 -105
  80. data/spec/lib/appsignal/rack/body_wrapper_spec.rb +263 -0
  81. data/spec/lib/appsignal/rack/event_handler_spec.rb +81 -78
  82. data/spec/lib/appsignal/rack/generic_instrumentation_spec.rb +70 -27
  83. data/spec/lib/appsignal/rack/grape_middleware_spec.rb +234 -0
  84. data/spec/lib/appsignal/rack/hanami_middleware_spec.rb +2 -16
  85. data/spec/lib/appsignal/rack/instrumentation_middleware_spec.rb +38 -0
  86. data/spec/lib/appsignal/rack/rails_instrumentation_spec.rb +67 -131
  87. data/spec/lib/appsignal/rack/sinatra_instrumentation_spec.rb +36 -44
  88. data/spec/lib/appsignal/rack/streaming_listener_spec.rb +44 -139
  89. data/spec/lib/appsignal/transaction_spec.rb +239 -94
  90. data/spec/lib/appsignal/utils/integration_memory_logger_spec.rb +163 -0
  91. data/spec/lib/appsignal_spec.rb +556 -344
  92. data/spec/support/helpers/dependency_helper.rb +6 -1
  93. data/spec/support/helpers/std_streams_helper.rb +1 -1
  94. data/spec/support/helpers/transaction_helpers.rb +8 -0
  95. data/spec/support/matchers/transaction.rb +185 -0
  96. data/spec/support/mocks/dummy_app.rb +20 -0
  97. data/spec/support/shared_examples/instrument.rb +17 -12
  98. data/spec/support/testing.rb +18 -9
  99. metadata +20 -11
  100. data/.semaphore/semaphore.yml +0 -2347
  101. data/script/lint_git +0 -22
  102. data/spec/lib/appsignal/integrations/grape_spec.rb +0 -239
  103. data/spec/support/matchers/be_completed.rb +0 -5
  104. data/support/check_versions +0 -22
  105. /data/gemfiles/{hanami.gemfile → hanami-2.0.gemfile} +0 -0
@@ -1,5 +1,5 @@
1
1
  describe Appsignal::Rack::AbstractMiddleware do
2
- let(:app) { double(:call => true) }
2
+ let(:app) { DummyApp.new }
3
3
  let(:request_path) { "/some/path" }
4
4
  let(:env) do
5
5
  Rack::MockRequest.env_for(
@@ -9,176 +9,292 @@ describe Appsignal::Rack::AbstractMiddleware do
9
9
  )
10
10
  end
11
11
  let(:options) { {} }
12
- let(:middleware) { Appsignal::Rack::AbstractMiddleware.new(app, options) }
12
+ let(:middleware) { described_class.new(app, options) }
13
13
 
14
14
  before(:context) { start_agent }
15
15
  around { |example| keep_transactions { example.run } }
16
16
 
17
- def make_request(env)
17
+ def make_request
18
18
  middleware.call(env)
19
19
  end
20
20
 
21
- def make_request_with_error(env, error)
22
- expect { make_request(env) }.to raise_error(error)
21
+ def make_request_with_error(error_class, error_message)
22
+ expect { make_request }.to raise_error(error_class, error_message)
23
23
  end
24
24
 
25
25
  describe "#call" do
26
- context "when appsignal is not active" do
26
+ context "when not active" do
27
27
  before { allow(Appsignal).to receive(:active?).and_return(false) }
28
28
 
29
- it "does not instrument requests" do
30
- expect { make_request(env) }.to_not(change { created_transactions.count })
29
+ it "does not instrument the request" do
30
+ expect { make_request }.to_not(change { created_transactions.count })
31
31
  end
32
32
 
33
33
  it "calls the next middleware in the stack" do
34
- expect(app).to receive(:call).with(env)
35
- make_request(env)
34
+ make_request
35
+ expect(app).to be_called
36
36
  end
37
37
  end
38
38
 
39
39
  context "when appsignal is active" do
40
40
  before { allow(Appsignal).to receive(:active?).and_return(true) }
41
41
 
42
- it "calls the next middleware in the stack" do
43
- make_request(env)
42
+ it "creates a transaction for the request" do
43
+ expect { make_request }.to(change { created_transactions.count }.by(1))
44
44
 
45
- expect(app).to have_received(:call).with(env)
45
+ expect(last_transaction).to have_namespace(Appsignal::Transaction::HTTP_REQUEST)
46
46
  end
47
47
 
48
- context "without an exception" do
49
- it "create a transaction for the request" do
50
- expect { make_request(env) }.to(change { created_transactions.count }.by(1))
48
+ it "wraps the response body in a BodyWrapper subclass" do
49
+ _status, _headers, body = make_request
50
+ expect(body).to be_kind_of(Appsignal::Rack::BodyWrapper)
51
+ end
51
52
 
52
- expect(last_transaction.to_h).to include(
53
- "namespace" => Appsignal::Transaction::HTTP_REQUEST,
54
- "action" => nil,
55
- "error" => nil
56
- )
53
+ context "without an error" do
54
+ before { make_request }
55
+
56
+ it "calls the next middleware in the stack" do
57
+ expect(app).to be_called
58
+ end
59
+
60
+ it "does not record an error" do
61
+ expect(last_transaction).to_not have_error
57
62
  end
58
63
 
59
- it "reports a process.abstract event" do
60
- make_request(env)
64
+ context "without :instrument_event_name option set" do
65
+ let(:options) { {} }
61
66
 
62
- expect(last_transaction.to_h).to include(
63
- "events" => [
64
- hash_including(
65
- "body" => "",
66
- "body_format" => Appsignal::EventFormatter::DEFAULT,
67
- "count" => 1,
68
- "name" => "process.abstract",
69
- "title" => ""
70
- )
71
- ]
72
- )
67
+ it "does not record an instrumentation event" do
68
+ expect(last_transaction).to_not include_event
69
+ end
70
+ end
71
+
72
+ context "with :instrument_event_name option set" do
73
+ let(:options) { { :instrument_event_name => "event_name.category" } }
74
+
75
+ it "records an instrumentation event" do
76
+ expect(last_transaction).to include_event(:name => "event_name.category")
77
+ end
73
78
  end
74
79
 
75
80
  it "completes the transaction" do
76
- make_request(env)
77
81
  expect(last_transaction).to be_completed
82
+ expect(Appsignal::Transaction.current)
83
+ .to be_kind_of(Appsignal::Transaction::NilTransaction)
84
+ end
85
+
86
+ context "when instrument_event_name option is nil" do
87
+ let(:options) { { :instrument_event_name => nil } }
88
+
89
+ it "does not record an instrumentation event" do
90
+ expect(last_transaction).to_not include_events
91
+ end
78
92
  end
79
93
  end
80
94
 
81
- context "with an exception" do
95
+ context "with an error" do
82
96
  let(:error) { ExampleException.new("error message") }
83
- before do
84
- allow(app).to receive(:call).and_raise(error)
85
- expect { make_request_with_error(env, error) }
97
+ let(:app) { lambda { |_env| raise ExampleException, "error message" } }
98
+
99
+ it "create a transaction for the request" do
100
+ expect { make_request_with_error(ExampleException, "error message") }
86
101
  .to(change { created_transactions.count }.by(1))
87
- end
88
102
 
89
- it "creates a transaction for the request and records the exception" do
90
- expect(last_transaction.to_h).to include(
91
- "error" => hash_including(
92
- "name" => "ExampleException",
93
- "message" => "error message"
94
- )
95
- )
103
+ expect(last_transaction).to have_namespace(Appsignal::Transaction::HTTP_REQUEST)
96
104
  end
97
105
 
98
- it "completes the transaction" do
99
- expect(last_transaction).to be_completed
106
+ describe "error" do
107
+ before do
108
+ make_request_with_error(ExampleException, "error message")
109
+ end
110
+
111
+ it "records the error" do
112
+ expect(last_transaction).to have_error("ExampleException", "error message")
113
+ end
114
+
115
+ it "completes the transaction" do
116
+ expect(last_transaction).to be_completed
117
+ expect(Appsignal::Transaction.current)
118
+ .to be_kind_of(Appsignal::Transaction::NilTransaction)
119
+ end
120
+
121
+ context "with :report_errors set to false" do
122
+ let(:app) { lambda { |_env| raise ExampleException, "error message" } }
123
+ let(:options) { { :report_errors => false } }
124
+
125
+ it "does not record the exception on the transaction" do
126
+ expect(last_transaction).to_not have_error
127
+ end
128
+ end
129
+
130
+ context "with :report_errors set to true" do
131
+ let(:app) { lambda { |_env| raise ExampleException, "error message" } }
132
+ let(:options) { { :report_errors => true } }
133
+
134
+ it "records the exception on the transaction" do
135
+ expect(last_transaction).to have_error("ExampleException", "error message")
136
+ end
137
+ end
138
+
139
+ context "with :report_errors set to a lambda that returns false" do
140
+ let(:app) { lambda { |_env| raise ExampleException, "error message" } }
141
+ let(:options) { { :report_errors => lambda { |_env| false } } }
142
+
143
+ it "does not record the exception on the transaction" do
144
+ expect(last_transaction).to_not have_error
145
+ end
146
+ end
147
+
148
+ context "with :report_errors set to a lambda that returns true" do
149
+ let(:app) { lambda { |_env| raise ExampleException, "error message" } }
150
+ let(:options) { { :report_errors => lambda { |_env| true } } }
151
+
152
+ it "records the exception on the transaction" do
153
+ expect(last_transaction).to have_error("ExampleException", "error message")
154
+ end
155
+ end
100
156
  end
101
157
  end
102
158
 
103
159
  context "without action name metadata" do
104
160
  it "reports no action name" do
105
- make_request(env)
161
+ make_request
106
162
 
107
- expect(last_transaction.to_h).to include("action" => nil)
163
+ expect(last_transaction).to_not have_action
108
164
  end
109
165
  end
110
166
 
111
167
  context "with appsignal.route env" do
112
- before do
113
- env["appsignal.route"] = "POST /my-route"
114
- end
168
+ before { env["appsignal.route"] = "POST /my-route" }
115
169
 
116
170
  it "reports the appsignal.route value as the action name" do
117
- make_request(env)
171
+ make_request
172
+
173
+ expect(last_transaction).to have_action("POST /my-route")
174
+ end
118
175
 
119
- expect(last_transaction.to_h).to include("action" => "POST /my-route")
176
+ it "prints a deprecation warning" do
177
+ err_stream = std_stream
178
+ capture_std_streams(std_stream, err_stream) do
179
+ make_request
180
+ end
181
+
182
+ expect(err_stream.read).to include(
183
+ "Setting the action name with the request env 'appsignal.route' is deprecated."
184
+ )
185
+ end
186
+
187
+ it "logs a deprecation warning" do
188
+ logs = capture_logs { make_request }
189
+ expect(logs).to contains_log(
190
+ :warn,
191
+ "Setting the action name with the request env 'appsignal.route' is deprecated."
192
+ )
120
193
  end
121
194
  end
122
195
 
123
196
  context "with appsignal.action env" do
124
- before do
125
- env["appsignal.action"] = "POST /my-action"
197
+ before { env["appsignal.action"] = "POST /my-action" }
198
+
199
+ it "reports the appsignal.action value as the action name" do
200
+ make_request
201
+
202
+ expect(last_transaction).to have_action("POST /my-action")
126
203
  end
127
204
 
128
- it "reports the appsignal.route value as the action name" do
129
- make_request(env)
205
+ it "prints a deprecation warning" do
206
+ err_stream = std_stream
207
+ capture_std_streams(std_stream, err_stream) do
208
+ make_request
209
+ end
130
210
 
131
- expect(last_transaction.to_h).to include("action" => "POST /my-action")
211
+ expect(err_stream.read).to include(
212
+ "Setting the action name with the request env 'appsignal.action' is deprecated."
213
+ )
132
214
  end
133
- end
134
215
 
135
- describe "request metadata" do
136
- before do
137
- env.merge("PATH_INFO" => "/some/path", "REQUEST_METHOD" => "GET")
216
+ it "logs a deprecation warning" do
217
+ logs = capture_logs { make_request }
218
+ expect(logs).to contains_log(
219
+ :warn,
220
+ "Setting the action name with the request env 'appsignal.action' is deprecated."
221
+ )
138
222
  end
223
+ end
139
224
 
225
+ describe "request metadata" do
140
226
  it "sets request metadata" do
141
- make_request(env)
142
-
143
- expect(last_transaction.to_h).to include(
144
- "metadata" => {
145
- "method" => "GET",
146
- "path" => "/some/path"
147
- },
148
- "sample_data" => hash_including(
149
- "environment" => hash_including(
150
- "REQUEST_METHOD" => "GET",
151
- "PATH_INFO" => "/some/path"
152
- # and more, but we don't need to test Rack mock defaults
153
- )
154
- )
227
+ env.merge!("PATH_INFO" => "/some/path", "REQUEST_METHOD" => "GET")
228
+ make_request
229
+
230
+ expect(last_transaction).to include_metadata(
231
+ "method" => "GET",
232
+ "path" => "/some/path"
155
233
  )
234
+ expect(last_transaction).to include_environment(
235
+ "REQUEST_METHOD" => "GET",
236
+ "PATH_INFO" => "/some/path"
237
+ # and more, but we don't need to test Rack mock defaults
238
+ )
239
+ end
240
+
241
+ context "with an invalid HTTP request method" do
242
+ it "stores the invalid HTTP request method" do
243
+ env["REQUEST_METHOD"] = "FOO"
244
+ make_request
245
+
246
+ expect(last_transaction).to include_metadata("method" => "FOO")
247
+ end
248
+ end
249
+
250
+ context "with fetching the request method raises an error" do
251
+ class BrokenRequestMethodRequest < Rack::Request
252
+ def request_method
253
+ raise "uh oh!"
254
+ end
255
+ end
256
+
257
+ let(:options) { { :request_class => BrokenRequestMethodRequest } }
258
+ it "does not store the invalid HTTP request method" do
259
+ env["REQUEST_METHOD"] = "FOO"
260
+ make_request
261
+
262
+ expect(last_transaction).to_not include_metadata("method" => anything)
263
+ end
156
264
  end
157
265
 
158
266
  it "sets request parameters" do
159
- make_request(env)
160
-
161
- expect(last_transaction.to_h).to include(
162
- "sample_data" => hash_including(
163
- "params" => hash_including(
164
- "page" => "2",
165
- "query" => "lorem"
166
- )
167
- )
267
+ make_request
268
+
269
+ expect(last_transaction).to include_params(
270
+ "page" => "2",
271
+ "query" => "lorem"
168
272
  )
169
273
  end
274
+
275
+ context "when setting custom params" do
276
+ let(:app) do
277
+ DummyApp.new do |_env|
278
+ Appsignal::Transaction.current.set_params("custom" => "param")
279
+ end
280
+ end
281
+
282
+ it "allow custom request parameters to be set" do
283
+ make_request
284
+
285
+ expect(last_transaction).to include_params("custom" => "param")
286
+ end
287
+ end
170
288
  end
171
289
 
172
290
  context "with queue start header" do
173
291
  let(:queue_start_time) { fixed_time * 1_000 }
174
- before do
175
- env["HTTP_X_REQUEST_START"] = "t=#{queue_start_time.to_i}" # in milliseconds
176
- end
177
292
 
178
293
  it "sets the queue start" do
179
- make_request(env)
294
+ env["HTTP_X_REQUEST_START"] = "t=#{queue_start_time.to_i}" # in milliseconds
295
+ make_request
180
296
 
181
- expect(last_transaction.ext.queue_start).to eq(queue_start_time)
297
+ expect(last_transaction).to have_queue_start(queue_start_time)
182
298
  end
183
299
  end
184
300
 
@@ -208,29 +324,66 @@ describe Appsignal::Rack::AbstractMiddleware do
208
324
  end
209
325
 
210
326
  it "uses the overridden request class and params method to fetch params" do
211
- make_request(env)
327
+ make_request
212
328
 
213
- expect(last_transaction.to_h).to include(
214
- "sample_data" => hash_including(
215
- "params" => { "abc" => "123" }
216
- )
217
- )
329
+ expect(last_transaction).to include_params("abc" => "123")
218
330
  end
219
331
  end
220
332
 
221
333
  context "with parent instrumentation" do
334
+ let(:transaction) { http_request_transaction }
222
335
  before do
223
- env[Appsignal::Rack::APPSIGNAL_TRANSACTION] = http_request_transaction
336
+ env[Appsignal::Rack::APPSIGNAL_TRANSACTION] = transaction
337
+ set_current_transaction(transaction)
224
338
  end
225
339
 
226
340
  it "uses the existing transaction" do
227
- make_request(env)
341
+ make_request
342
+
343
+ expect { make_request }.to_not(change { created_transactions.count })
344
+ end
345
+
346
+ it "wraps the response body in a BodyWrapper subclass" do
347
+ _status, _headers, body = make_request
348
+ expect(body).to be_kind_of(Appsignal::Rack::BodyWrapper)
228
349
 
229
- expect { make_request(env) }.to_not(change { created_transactions.count })
350
+ body.to_ary
351
+ response_events =
352
+ last_transaction.to_h["events"].count do |event|
353
+ event["name"] == "process_response_body.rack"
354
+ end
355
+ expect(response_events).to eq(1)
356
+ end
357
+
358
+ context "when response body is already a BodyWrapper subclass" do
359
+ let(:body) { Appsignal::Rack::BodyWrapper.wrap(["hello!"], transaction) }
360
+ let(:app) { DummyApp.new { [200, {}, body] } }
361
+
362
+ it "doesn't wrap the body again" do
363
+ _status, _headers, body = make_request
364
+ expect(body).to eq(body)
365
+
366
+ body.to_ary
367
+ response_events =
368
+ last_transaction.to_h["events"].count do |event|
369
+ event["name"] == "process_response_body.rack"
370
+ end
371
+ expect(response_events).to eq(1)
372
+ end
373
+ end
374
+
375
+ context "with error" do
376
+ let(:app) { lambda { |_env| raise ExampleException, "error message" } }
377
+
378
+ it "doesn't record the error on the transaction" do
379
+ make_request_with_error(ExampleException, "error message")
380
+
381
+ expect(last_transaction).to_not have_error
382
+ end
230
383
  end
231
384
 
232
385
  it "doesn't complete the existing transaction" do
233
- make_request(env)
386
+ make_request
234
387
 
235
388
  expect(env[Appsignal::Rack::APPSIGNAL_TRANSACTION]).to_not be_completed
236
389
  end
@@ -239,9 +392,53 @@ describe Appsignal::Rack::AbstractMiddleware do
239
392
  it "does not overwrite the action name" do
240
393
  env[Appsignal::Rack::APPSIGNAL_TRANSACTION].set_action("My custom action")
241
394
  env["appsignal.action"] = "POST /my-action"
242
- make_request(env)
395
+ make_request
396
+
397
+ expect(last_transaction).to have_action("My custom action")
398
+ end
399
+ end
400
+
401
+ context "with :report_errors set to false" do
402
+ let(:app) { lambda { |_env| raise ExampleException, "error message" } }
403
+ let(:options) { { :report_errors => false } }
404
+
405
+ it "does not record the error on the transaction" do
406
+ make_request_with_error(ExampleException, "error message")
407
+
408
+ expect(last_transaction).to_not have_error
409
+ end
410
+ end
411
+
412
+ context "with :report_errors set to true" do
413
+ let(:app) { lambda { |_env| raise ExampleException, "error message" } }
414
+ let(:options) { { :report_errors => true } }
415
+
416
+ it "records the error on the transaction" do
417
+ make_request_with_error(ExampleException, "error message")
418
+
419
+ expect(last_transaction).to have_error("ExampleException", "error message")
420
+ end
421
+ end
422
+
423
+ context "with :report_errors set to a lambda that returns false" do
424
+ let(:app) { lambda { |_env| raise ExampleException, "error message" } }
425
+ let(:options) { { :report_errors => lambda { |_env| false } } }
426
+
427
+ it "does not record the exception on the transaction" do
428
+ make_request_with_error(ExampleException, "error message")
429
+
430
+ expect(last_transaction).to_not have_error
431
+ end
432
+ end
433
+
434
+ context "with :report_errors set to a lambda that returns true" do
435
+ let(:app) { lambda { |_env| raise ExampleException, "error message" } }
436
+ let(:options) { { :report_errors => lambda { |_env| true } } }
437
+
438
+ it "records the error on the transaction" do
439
+ make_request_with_error(ExampleException, "error message")
243
440
 
244
- expect(last_transaction.to_h).to include("action" => "My custom action")
441
+ expect(last_transaction).to have_error("ExampleException", "error message")
245
442
  end
246
443
  end
247
444
  end