appsignal 2.1.2 → 2.2.0.beta.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (114) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +14 -0
  3. data/.rubocop_todo.yml +16 -171
  4. data/.travis.yml +14 -1
  5. data/.yardopts +8 -0
  6. data/CHANGELOG.md +21 -3
  7. data/README.md +20 -2
  8. data/Rakefile +60 -62
  9. data/appsignal.gemspec +24 -23
  10. data/ext/agent.yml +11 -11
  11. data/ext/appsignal_extension.c +43 -12
  12. data/ext/extconf.rb +9 -9
  13. data/gemfiles/padrino.gemfile +1 -1
  14. data/lib/appsignal.rb +403 -26
  15. data/lib/appsignal/auth_check.rb +28 -1
  16. data/lib/appsignal/cli.rb +1 -0
  17. data/lib/appsignal/cli/demo.rb +40 -0
  18. data/lib/appsignal/cli/diagnose.rb +345 -89
  19. data/lib/appsignal/cli/helpers.rb +9 -4
  20. data/lib/appsignal/cli/install.rb +6 -6
  21. data/lib/appsignal/cli/notify_of_deploy.rb +58 -0
  22. data/lib/appsignal/config.rb +40 -38
  23. data/lib/appsignal/demo.rb +20 -0
  24. data/lib/appsignal/event_formatter.rb +4 -0
  25. data/lib/appsignal/event_formatter/action_view/render_formatter.rb +1 -0
  26. data/lib/appsignal/event_formatter/active_record/instantiation_formatter.rb +1 -0
  27. data/lib/appsignal/event_formatter/active_record/sql_formatter.rb +1 -0
  28. data/lib/appsignal/event_formatter/elastic_search/search_formatter.rb +1 -0
  29. data/lib/appsignal/event_formatter/faraday/request_formatter.rb +1 -0
  30. data/lib/appsignal/event_formatter/mongo_ruby_driver/query_formatter.rb +2 -1
  31. data/lib/appsignal/event_formatter/moped/query_formatter.rb +1 -0
  32. data/lib/appsignal/extension.rb +1 -0
  33. data/lib/appsignal/garbage_collection_profiler.rb +20 -19
  34. data/lib/appsignal/hooks.rb +1 -0
  35. data/lib/appsignal/hooks/active_support_notifications.rb +1 -0
  36. data/lib/appsignal/hooks/celluloid.rb +1 -0
  37. data/lib/appsignal/hooks/data_mapper.rb +1 -0
  38. data/lib/appsignal/hooks/delayed_job.rb +1 -0
  39. data/lib/appsignal/hooks/mongo_ruby_driver.rb +1 -0
  40. data/lib/appsignal/hooks/net_http.rb +1 -0
  41. data/lib/appsignal/hooks/passenger.rb +1 -0
  42. data/lib/appsignal/hooks/puma.rb +1 -0
  43. data/lib/appsignal/hooks/rake.rb +1 -0
  44. data/lib/appsignal/hooks/redis.rb +1 -0
  45. data/lib/appsignal/hooks/sequel.rb +1 -0
  46. data/lib/appsignal/hooks/shoryuken.rb +1 -0
  47. data/lib/appsignal/hooks/sidekiq.rb +1 -0
  48. data/lib/appsignal/hooks/unicorn.rb +1 -0
  49. data/lib/appsignal/hooks/webmachine.rb +1 -0
  50. data/lib/appsignal/integrations/capistrano/appsignal.cap +4 -4
  51. data/lib/appsignal/integrations/capistrano/capistrano_2_tasks.rb +2 -0
  52. data/lib/appsignal/integrations/data_mapper.rb +1 -1
  53. data/lib/appsignal/integrations/delayed_job_plugin.rb +1 -0
  54. data/lib/appsignal/integrations/grape.rb +3 -1
  55. data/lib/appsignal/integrations/mongo_ruby_driver.rb +1 -0
  56. data/lib/appsignal/integrations/padrino.rb +36 -21
  57. data/lib/appsignal/integrations/railtie.rb +2 -2
  58. data/lib/appsignal/integrations/resque.rb +1 -0
  59. data/lib/appsignal/integrations/resque_active_job.rb +1 -0
  60. data/lib/appsignal/integrations/webmachine.rb +27 -24
  61. data/lib/appsignal/js_exception_transaction.rb +8 -8
  62. data/lib/appsignal/marker.rb +41 -4
  63. data/lib/appsignal/minutely.rb +1 -0
  64. data/lib/appsignal/rack/generic_instrumentation.rb +3 -2
  65. data/lib/appsignal/rack/js_exception_catcher.rb +55 -15
  66. data/lib/appsignal/rack/rails_instrumentation.rb +2 -1
  67. data/lib/appsignal/rack/sinatra_instrumentation.rb +4 -2
  68. data/lib/appsignal/rack/streaming_listener.rb +4 -2
  69. data/lib/appsignal/system.rb +5 -31
  70. data/lib/appsignal/transaction.rb +71 -6
  71. data/lib/appsignal/transmitter.rb +24 -13
  72. data/lib/appsignal/utils.rb +18 -11
  73. data/lib/appsignal/utils/params_sanitizer.rb +2 -1
  74. data/lib/appsignal/utils/query_params_sanitizer.rb +1 -0
  75. data/lib/appsignal/version.rb +1 -1
  76. data/resources/appsignal.yml.erb +1 -1
  77. data/spec/lib/appsignal/auth_check_spec.rb +64 -22
  78. data/spec/lib/appsignal/cli/diagnose_spec.rb +539 -81
  79. data/spec/lib/appsignal/cli/helpers_spec.rb +74 -2
  80. data/spec/lib/appsignal/cli/install_spec.rb +3 -3
  81. data/spec/lib/appsignal/config_spec.rb +38 -72
  82. data/spec/lib/appsignal/demo_spec.rb +2 -2
  83. data/spec/lib/appsignal/event_formatter_spec.rb +2 -2
  84. data/spec/lib/appsignal/extension_spec.rb +4 -0
  85. data/spec/lib/appsignal/garbage_collection_profiler_spec.rb +18 -21
  86. data/spec/lib/appsignal/hooks/mongo_ruby_driver_spec.rb +1 -1
  87. data/spec/lib/appsignal/hooks/redis_spec.rb +34 -44
  88. data/spec/lib/appsignal/hooks/sidekiq_spec.rb +2 -2
  89. data/spec/lib/appsignal/integrations/grape_spec.rb +6 -6
  90. data/spec/lib/appsignal/integrations/padrino_spec.rb +241 -122
  91. data/spec/lib/appsignal/integrations/railtie_spec.rb +34 -16
  92. data/spec/lib/appsignal/integrations/resque_spec.rb +1 -1
  93. data/spec/lib/appsignal/integrations/sinatra_spec.rb +38 -10
  94. data/spec/lib/appsignal/integrations/webmachine_spec.rb +2 -2
  95. data/spec/lib/appsignal/rack/generic_instrumentation_spec.rb +7 -6
  96. data/spec/lib/appsignal/rack/js_exception_catcher_spec.rb +95 -58
  97. data/spec/lib/appsignal/rack/rails_instrumentation_spec.rb +9 -6
  98. data/spec/lib/appsignal/rack/sinatra_instrumentation_spec.rb +11 -10
  99. data/spec/lib/appsignal/rack/streaming_listener_spec.rb +20 -13
  100. data/spec/lib/appsignal/system_spec.rb +2 -32
  101. data/spec/lib/appsignal/transaction_spec.rb +48 -7
  102. data/spec/lib/appsignal/transmitter_spec.rb +52 -33
  103. data/spec/lib/appsignal/utils/params_sanitizer_spec.rb +3 -1
  104. data/spec/lib/appsignal/utils/query_params_sanitizer_spec.rb +3 -3
  105. data/spec/lib/appsignal/utils_spec.rb +49 -6
  106. data/spec/lib/appsignal_spec.rb +60 -5
  107. data/spec/spec_helper.rb +4 -3
  108. data/spec/support/helpers/api_request_helper.rb +1 -4
  109. data/spec/support/helpers/dependency_helper.rb +4 -0
  110. data/spec/support/helpers/system_helpers.rb +1 -17
  111. data/spec/support/helpers/time_helpers.rb +1 -1
  112. metadata +19 -8
  113. data/spec/lib/appsignal/system/container_spec.rb +0 -67
  114. data/spec/lib/appsignal/utils/gzip_spec.rb +0 -10
@@ -66,29 +66,33 @@ if DependencyHelper.rails_present?
66
66
  end
67
67
  end
68
68
 
69
- context "listener middleware" do
70
- it "should have added the listener middleware" do
69
+ describe "Rails listener middleware" do
70
+ it "adds the Rails listener middleware" do
71
71
  expect(app.middleware).to receive(:insert_before).with(
72
72
  ActionDispatch::RemoteIp,
73
73
  Appsignal::Rack::RailsInstrumentation
74
74
  )
75
75
  end
76
76
 
77
- context "when frontend_error_catching is enabled" do
78
- let(:config) do
79
- Appsignal::Config.new(
80
- project_fixture_path,
81
- "test",
82
- :name => "MyApp",
83
- :enable_frontend_error_catching => true
84
- )
85
- end
77
+ after { Appsignal::Integrations::Railtie.initialize_appsignal(app) }
78
+ end
86
79
 
87
- before do
88
- allow(Appsignal).to receive(:config).and_return(config)
89
- end
80
+ describe "frontend_error_catching middleware" do
81
+ let(:config) do
82
+ Appsignal::Config.new(
83
+ project_fixture_path,
84
+ "test",
85
+ :name => "MyApp",
86
+ :enable_frontend_error_catching => enable_frontend_error_catching
87
+ )
88
+ end
89
+ before { allow(Appsignal::Config).to receive(:new).and_return(config) }
90
+ after { Appsignal::Integrations::Railtie.initialize_appsignal(app) }
90
91
 
91
- it "should have added the listener and JSExceptionCatcher middleware" do
92
+ context "when enabled" do
93
+ let(:enable_frontend_error_catching) { true }
94
+
95
+ it "adds the Rails and JSExceptionCatcher middleware" do
92
96
  expect(app.middleware).to receive(:insert_before).with(
93
97
  ActionDispatch::RemoteIp,
94
98
  Appsignal::Rack::RailsInstrumentation
@@ -101,7 +105,21 @@ if DependencyHelper.rails_present?
101
105
  end
102
106
  end
103
107
 
104
- after { Appsignal::Integrations::Railtie.initialize_appsignal(app) }
108
+ context "when not enabled" do
109
+ let(:enable_frontend_error_catching) { false }
110
+
111
+ it "adds the Rails middleware, but not the JSExceptionCatcher middleware" do
112
+ expect(app.middleware).to receive(:insert_before).with(
113
+ ActionDispatch::RemoteIp,
114
+ Appsignal::Rack::RailsInstrumentation
115
+ )
116
+
117
+ expect(app.middleware).to_not receive(:insert_before).with(
118
+ Appsignal::Rack::RailsInstrumentation,
119
+ Appsignal::Rack::JSExceptionCatcher
120
+ )
121
+ end
122
+ end
105
123
  end
106
124
  end
107
125
  end
@@ -18,7 +18,7 @@ if DependencyHelper.resque_present?
18
18
  extend Appsignal::Integrations::ResquePlugin
19
19
 
20
20
  def self.perform
21
- raise VerySpecificError.new
21
+ raise VerySpecificError
22
22
  end
23
23
  end
24
24
  end
@@ -1,19 +1,49 @@
1
1
  if DependencyHelper.sinatra_present?
2
- ENV["APPSIGNAL_PUSH_API_KEY"] = "key"
3
2
  require "appsignal/integrations/sinatra"
4
3
 
4
+ def install_sinatra_integration
5
+ load File.expand_path("lib/appsignal/integrations/sinatra.rb", project_dir)
6
+ end
7
+
8
+ # "Uninstall" the AppSignal integration
9
+ def uninstall_sinatra_integration
10
+ Sinatra::Base.instance_variable_get(:@middleware).delete_if do |middleware|
11
+ middleware.first == Appsignal::Rack::SinatraBaseInstrumentation
12
+ end
13
+ end
14
+
5
15
  describe "Sinatra integration" do
16
+ before { allow(Appsignal).to receive(:active?).and_return(true) }
17
+ after { uninstall_sinatra_integration }
18
+
6
19
  context "Appsignal.logger" do
7
20
  subject { Appsignal.logger }
8
21
 
9
- it { is_expected.to be_a Logger }
22
+ it "sets a logger" do
23
+ install_sinatra_integration
24
+ is_expected.to be_a Logger
25
+ end
10
26
  end
11
27
 
12
28
  describe "middleware" do
13
- it "adds the instrumentation middleware to Sinatra::Base" do
14
- expect(Sinatra::Base.middleware.to_a).to include(
15
- [Appsignal::Rack::SinatraBaseInstrumentation, [], nil]
16
- )
29
+ context "when AppSignal is not active" do
30
+ before { allow(Appsignal).to receive(:active?).and_return(false) }
31
+
32
+ it "does not add the instrumentation middleware to Sinatra::Base" do
33
+ install_sinatra_integration
34
+ expect(Sinatra::Base.middleware.to_a).to_not include(
35
+ [Appsignal::Rack::SinatraBaseInstrumentation, [], nil]
36
+ )
37
+ end
38
+ end
39
+
40
+ context "when AppSignal is active" do
41
+ it "adds the instrumentation middleware to Sinatra::Base" do
42
+ install_sinatra_integration
43
+ expect(Sinatra::Base.middleware.to_a).to include(
44
+ [Appsignal::Rack::SinatraBaseInstrumentation, [], nil]
45
+ )
46
+ end
17
47
  end
18
48
  end
19
49
 
@@ -21,9 +51,7 @@ if DependencyHelper.sinatra_present?
21
51
  subject { Appsignal.config.env }
22
52
 
23
53
  context "without APPSIGNAL_APP_ENV" do
24
- before do
25
- load File.expand_path("lib/appsignal/integrations/sinatra.rb", project_dir)
26
- end
54
+ before { install_sinatra_integration }
27
55
 
28
56
  it "uses the app environment" do
29
57
  expect(subject).to eq("test")
@@ -33,7 +61,7 @@ if DependencyHelper.sinatra_present?
33
61
  context "with APPSIGNAL_APP_ENV" do
34
62
  before do
35
63
  ENV["APPSIGNAL_APP_ENV"] = "env-staging"
36
- load File.expand_path("lib/appsignal/integrations/sinatra.rb", project_dir)
64
+ install_sinatra_integration
37
65
  end
38
66
 
39
67
  it "uses the environment variable" do
@@ -7,7 +7,7 @@ if DependencyHelper.webmachine_present?
7
7
  end
8
8
  let(:resource) { double(:trace? => false, :handle_exception => true) }
9
9
  let(:response) { double }
10
- let(:transaction) { double(:set_action => true) }
10
+ let(:transaction) { double(:set_action_if_nil => true) }
11
11
  let(:fsm) { Webmachine::Decision::FSM.new(resource, request, response) }
12
12
  before(:context) { start_agent }
13
13
 
@@ -36,7 +36,7 @@ if DependencyHelper.webmachine_present?
36
36
  end
37
37
 
38
38
  it "should set the action" do
39
- expect(transaction).to receive(:set_action).with("RSpec::Mocks::Mock#GET")
39
+ expect(transaction).to receive(:set_action_if_nil).with("RSpec::Mocks::Mock#GET")
40
40
  end
41
41
 
42
42
  it "should call the original method" do
@@ -36,20 +36,20 @@ describe Appsignal::Rack::GenericInstrumentation do
36
36
  after { middleware.call(env) }
37
37
  end
38
38
 
39
- describe "#call_with_appsignal_monitoring" do
39
+ describe "#call_with_appsignal_monitoring", :error => false do
40
40
  it "should create a transaction" do
41
41
  expect(Appsignal::Transaction).to receive(:create).with(
42
42
  kind_of(String),
43
43
  Appsignal::Transaction::HTTP_REQUEST,
44
44
  kind_of(Rack::Request)
45
- ).and_return(double(:set_action => nil, :set_http_or_background_queue_start => nil, :set_metadata => nil))
45
+ ).and_return(double(:set_action_if_nil => nil, :set_http_or_background_queue_start => nil, :set_metadata => nil))
46
46
  end
47
47
 
48
48
  it "should call the app" do
49
49
  expect(app).to receive(:call).with(env)
50
50
  end
51
51
 
52
- context "with an error" do
52
+ context "with an error", :error => true do
53
53
  let(:error) { VerySpecificError.new }
54
54
  let(:app) do
55
55
  double.tap do |d|
@@ -63,7 +63,7 @@ describe Appsignal::Rack::GenericInstrumentation do
63
63
  end
64
64
 
65
65
  it "should set the action to unknown" do
66
- expect_any_instance_of(Appsignal::Transaction).to receive(:set_action).with("unknown")
66
+ expect_any_instance_of(Appsignal::Transaction).to receive(:set_action_if_nil).with("unknown")
67
67
  end
68
68
 
69
69
  context "with a route specified in the env" do
@@ -72,7 +72,7 @@ describe Appsignal::Rack::GenericInstrumentation do
72
72
  end
73
73
 
74
74
  it "should set the action" do
75
- expect_any_instance_of(Appsignal::Transaction).to receive(:set_action).with("GET /")
75
+ expect_any_instance_of(Appsignal::Transaction).to receive(:set_action_if_nil).with("GET /")
76
76
  end
77
77
  end
78
78
 
@@ -84,6 +84,7 @@ describe Appsignal::Rack::GenericInstrumentation do
84
84
  expect_any_instance_of(Appsignal::Transaction).to receive(:set_http_or_background_queue_start)
85
85
  end
86
86
 
87
- after { middleware.call(env) rescue VerySpecificError }
87
+ after(:error => false) { middleware.call(env) }
88
+ after(:error => true) { expect { middleware.call(env) }.to raise_error(VerySpecificError) }
88
89
  end
89
90
  end
@@ -1,17 +1,12 @@
1
1
  describe Appsignal::Rack::JSExceptionCatcher do
2
2
  let(:app) { double(:call => true) }
3
- let(:options) { double }
4
- let(:active) { true }
3
+ let(:options) { nil }
5
4
  let(:config_options) { { :enable_frontend_error_catching => true } }
6
5
  let(:config) { project_fixture_config("production", config_options) }
7
-
8
- before do
9
- allow(Appsignal).to receive(:config).and_return(config)
10
- allow(config).to receive(:active?).and_return(active)
11
- end
6
+ before { Appsignal.config = config }
12
7
 
13
8
  describe "#initialize" do
14
- it "should log to the logger" do
9
+ it "logs to the logger" do
15
10
  expect(Appsignal.logger).to receive(:debug)
16
11
  .with("Initializing Appsignal::Rack::JSExceptionCatcher")
17
12
 
@@ -21,16 +16,29 @@ describe Appsignal::Rack::JSExceptionCatcher do
21
16
 
22
17
  describe "#call" do
23
18
  let(:catcher) { Appsignal::Rack::JSExceptionCatcher.new(app, options) }
19
+ after { catcher.call(env) }
24
20
 
25
- context "when path is not `/appsignal_error_catcher`" do
21
+ context "when path is not frontend_error_catching_path" do
26
22
  let(:env) { { "PATH_INFO" => "/foo" } }
27
23
 
28
- it "should call the next middleware" do
29
- expect(app).to receive(:call).with(env)
24
+ context "when AppSignal is not active" do
25
+ before { config[:active] = false }
26
+
27
+ it "calls the next middleware" do
28
+ expect(app).to receive(:call).with(env)
29
+ end
30
+ end
31
+
32
+ context "when AppSignal is active" do
33
+ before { config[:active] = true }
34
+
35
+ it "calls the next middleware" do
36
+ expect(app).to receive(:call).with(env)
37
+ end
30
38
  end
31
39
  end
32
40
 
33
- context "when path is `/appsignal_error_catcher`" do
41
+ context "when path is frontend_error_catching_path" do
34
42
  let(:transaction) { double(:complete! => true) }
35
43
  let(:env) do
36
44
  {
@@ -39,72 +47,101 @@ describe Appsignal::Rack::JSExceptionCatcher do
39
47
  }
40
48
  end
41
49
 
42
- it "should create a JSExceptionTransaction" do
43
- expect(Appsignal::JSExceptionTransaction).to receive(:new)
44
- .with("name" => "error")
45
- .and_return(transaction)
50
+ context "when AppSignal is not active" do
51
+ before { config[:active] = false }
52
+
53
+ it "doesn't create an AppSignal transaction" do
54
+ expect(Appsignal::JSExceptionTransaction).to_not receive(:new)
55
+ end
46
56
 
47
- expect(transaction).to receive(:complete!)
57
+ it "returns a 202 status" do
58
+ expect(catcher.call(env)).to eq(
59
+ [202, {}, ["AppSignal JavaScript error catching endpoint is not active."]]
60
+ )
61
+ end
48
62
  end
49
63
 
50
- it "should return 200" do
51
- allow(Appsignal::JSExceptionTransaction).to receive(:new)
52
- .and_return(transaction)
64
+ context "when AppSignal is active" do
65
+ before { config[:active] = true }
53
66
 
54
- expect(catcher.call(env)).to eql([200, {}, []])
55
- end
67
+ it "creates a JSExceptionTransaction" do
68
+ expect(Appsignal::JSExceptionTransaction).to receive(:new)
69
+ .with("name" => "error")
70
+ .and_return(transaction)
56
71
 
57
- context "when `frontend_error_catching_path` is different" do
58
- let(:config_options) do
59
- {
60
- :frontend_error_catching_path => "/foo"
61
- }
72
+ expect(transaction).to receive(:complete!)
62
73
  end
63
74
 
64
- it "should not create a transaction" do
65
- expect(Appsignal::JSExceptionTransaction).to_not receive(:new)
66
- end
75
+ it "returns 200" do
76
+ allow(Appsignal::JSExceptionTransaction).to receive(:new)
77
+ .and_return(transaction)
67
78
 
68
- it "should call the next middleware" do
69
- expect(app).to receive(:call).with(env)
79
+ expect(catcher.call(env)).to eq([200, {}, []])
70
80
  end
71
- end
72
81
 
73
- context "when `name` is empty" do
74
- let(:env) do
75
- {
76
- "PATH_INFO" => "/appsignal_error_catcher",
77
- "rack.input" => double(:read => '{"name": ""}')
78
- }
82
+ context "when request payload is empty" do
83
+ let(:env) do
84
+ {
85
+ "PATH_INFO" => "/appsignal_error_catcher",
86
+ "rack.input" => double(:read => "")
87
+ }
88
+ end
89
+
90
+ it "does not create a transaction" do
91
+ expect(Appsignal::JSExceptionTransaction).to_not receive(:new)
92
+ end
93
+
94
+ it "returns 400" do
95
+ expect(catcher.call(env)).to eq([400, {}, ["Request payload is not valid JSON."]])
96
+ end
79
97
  end
80
98
 
81
- it "should not create a transaction" do
82
- expect(Appsignal::JSExceptionTransaction).to_not receive(:new)
83
- end
99
+ context "when `frontend_error_catching_path` is different" do
100
+ let(:config_options) { { :frontend_error_catching_path => "/foo" } }
84
101
 
85
- it "should return 422" do
86
- expect(catcher.call(env)).to eql([422, {}, []])
87
- end
88
- end
102
+ it "does not create a transaction" do
103
+ expect(Appsignal::JSExceptionTransaction).to_not receive(:new)
104
+ end
89
105
 
90
- context "when `name` doesn't exist" do
91
- let(:env) do
92
- {
93
- "PATH_INFO" => "/appsignal_error_catcher",
94
- "rack.input" => double(:read => '{"foo": ""}')
95
- }
106
+ it "calls the next middleware" do
107
+ expect(app).to receive(:call).with(env)
108
+ end
96
109
  end
97
110
 
98
- it "should not create a transaction" do
99
- expect(Appsignal::JSExceptionTransaction).to_not receive(:new)
111
+ context "when `name` is empty" do
112
+ let(:env) do
113
+ {
114
+ "PATH_INFO" => "/appsignal_error_catcher",
115
+ "rack.input" => double(:read => '{"name": ""}')
116
+ }
117
+ end
118
+
119
+ it "does not create a transaction" do
120
+ expect(Appsignal::JSExceptionTransaction).to_not receive(:new)
121
+ end
122
+
123
+ it "returns 422" do
124
+ expect(catcher.call(env)).to eq([422, {}, []])
125
+ end
100
126
  end
101
127
 
102
- it "should return 422" do
103
- expect(catcher.call(env)).to eql([422, {}, []])
128
+ context "when `name` doesn't exist" do
129
+ let(:env) do
130
+ {
131
+ "PATH_INFO" => "/appsignal_error_catcher",
132
+ "rack.input" => double(:read => '{"foo": ""}')
133
+ }
134
+ end
135
+
136
+ it "does not create a transaction" do
137
+ expect(Appsignal::JSExceptionTransaction).to_not receive(:new)
138
+ end
139
+
140
+ it "returns 422" do
141
+ expect(catcher.call(env)).to eq([422, {}, []])
142
+ end
104
143
  end
105
144
  end
106
145
  end
107
-
108
- after { catcher.call(env) }
109
146
  end
110
147
  end
@@ -46,7 +46,7 @@ if DependencyHelper.rails_present?
46
46
  after { middleware.call(env) }
47
47
  end
48
48
 
49
- describe "#call_with_appsignal_monitoring" do
49
+ describe "#call_with_appsignal_monitoring", :error => false do
50
50
  it "should create a transaction" do
51
51
  expect(Appsignal::Transaction).to receive(:create).with(
52
52
  "1",
@@ -54,8 +54,10 @@ if DependencyHelper.rails_present?
54
54
  kind_of(ActionDispatch::Request),
55
55
  :params_method => :filtered_parameters
56
56
  ).and_return(
57
- double(
57
+ instance_double(
58
+ "Appsignal::Transaction",
58
59
  :set_action => nil,
60
+ :set_action_if_nil => nil,
59
61
  :set_http_or_background_queue_start => nil,
60
62
  :set_metadata => nil
61
63
  )
@@ -66,8 +68,8 @@ if DependencyHelper.rails_present?
66
68
  expect(app).to receive(:call).with(env)
67
69
  end
68
70
 
69
- context "with an error" do
70
- let(:error) { VerySpecificError.new }
71
+ context "with an error", :error => true do
72
+ let(:error) { VerySpecificError }
71
73
  let(:app) do
72
74
  double.tap do |d|
73
75
  allow(d).to receive(:call).and_raise(error)
@@ -84,11 +86,12 @@ if DependencyHelper.rails_present?
84
86
  end
85
87
 
86
88
  it "should set the action and queue start" do
87
- expect_any_instance_of(Appsignal::Transaction).to receive(:set_action).with("MockController#index")
89
+ expect_any_instance_of(Appsignal::Transaction).to receive(:set_action_if_nil).with("MockController#index")
88
90
  expect_any_instance_of(Appsignal::Transaction).to receive(:set_http_or_background_queue_start)
89
91
  end
90
92
 
91
- after { middleware.call(env) rescue VerySpecificError }
93
+ after(:error => false) { middleware.call(env) }
94
+ after(:error => true) { expect { middleware.call(env) }.to raise_error(VerySpecificError) }
92
95
  end
93
96
 
94
97
  describe "#request_id" do