airbrake 4.3.8 → 5.0.0.rc.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (134) hide show
  1. checksums.yaml +4 -4
  2. data/lib/airbrake.rb +16 -185
  3. data/lib/airbrake/capistrano/tasks.rb +64 -0
  4. data/lib/airbrake/delayed_job/plugin.rb +48 -0
  5. data/lib/airbrake/rack/middleware.rb +45 -0
  6. data/lib/airbrake/rack/notice_builder.rb +80 -0
  7. data/lib/airbrake/rack/user.rb +51 -0
  8. data/lib/airbrake/rails/action_controller.rb +35 -0
  9. data/lib/airbrake/rails/active_job.rb +23 -0
  10. data/lib/airbrake/rails/active_record.rb +40 -0
  11. data/lib/airbrake/rails/railtie.rb +61 -0
  12. data/lib/airbrake/rake/task_ext.rb +61 -0
  13. data/lib/airbrake/rake/tasks.rb +93 -0
  14. data/lib/airbrake/resque/failure.rb +19 -0
  15. data/lib/airbrake/sidekiq/error_handler.rb +35 -0
  16. data/lib/airbrake/version.rb +4 -1
  17. data/lib/generators/airbrake_generator.rb +25 -0
  18. data/lib/generators/airbrake_initializer.rb.erb +55 -0
  19. data/spec/airbrake_spec.rb +0 -0
  20. data/spec/apps/rack/dummy_app.rb +17 -0
  21. data/spec/apps/rails/dummy_app.rb +150 -0
  22. data/spec/apps/rails/dummy_task.rake +20 -0
  23. data/spec/apps/rails/logs/32.log +13358 -0
  24. data/spec/apps/rails/logs/40.log +6854 -0
  25. data/spec/apps/rails/logs/41.log +3170 -0
  26. data/spec/apps/rails/logs/42.log +23919 -0
  27. data/spec/apps/rails/logs/50.log +10976 -0
  28. data/spec/apps/sinatra/dummy_app.rb +12 -0
  29. data/spec/integration/rack/rack_spec.rb +17 -0
  30. data/spec/integration/rails/rails_spec.rb +135 -0
  31. data/spec/integration/rails/rake_spec.rb +160 -0
  32. data/spec/integration/shared_examples/rack_examples.rb +106 -0
  33. data/spec/integration/sinatra/sinatra_spec.rb +15 -0
  34. data/spec/spec_helper.rb +127 -0
  35. data/spec/unit/rack/middleware_spec.rb +80 -0
  36. data/spec/unit/rack/notice_builder_spec.rb +35 -0
  37. data/spec/unit/rack/user_spec.rb +78 -0
  38. data/spec/unit/rake/tasks_spec.rb +40 -0
  39. data/spec/unit/sidekiq/error_handler_spec.rb +29 -0
  40. metadata +110 -325
  41. data/CHANGELOG +0 -1716
  42. data/Gemfile +0 -3
  43. data/Guardfile +0 -6
  44. data/INSTALL +0 -20
  45. data/LICENSE +0 -61
  46. data/README.md +0 -148
  47. data/README_FOR_HEROKU_ADDON.md +0 -102
  48. data/Rakefile +0 -179
  49. data/TESTED_AGAINST +0 -7
  50. data/airbrake.gemspec +0 -41
  51. data/bin/airbrake +0 -12
  52. data/features/metal.feature +0 -34
  53. data/features/rack.feature +0 -60
  54. data/features/rails.feature +0 -324
  55. data/features/rake.feature +0 -33
  56. data/features/sinatra.feature +0 -126
  57. data/features/step_definitions/file_steps.rb +0 -14
  58. data/features/step_definitions/rack_steps.rb +0 -27
  59. data/features/step_definitions/rails_application_steps.rb +0 -267
  60. data/features/step_definitions/rake_steps.rb +0 -22
  61. data/features/support/airbrake_shim.rb.template +0 -11
  62. data/features/support/aruba.rb +0 -5
  63. data/features/support/env.rb +0 -39
  64. data/features/support/matchers.rb +0 -35
  65. data/features/support/rails.rb +0 -156
  66. data/features/support/rake/Rakefile +0 -77
  67. data/features/user_informer.feature +0 -57
  68. data/generators/airbrake/airbrake_generator.rb +0 -94
  69. data/generators/airbrake/lib/insert_commands.rb +0 -34
  70. data/generators/airbrake/lib/rake_commands.rb +0 -24
  71. data/generators/airbrake/templates/airbrake_tasks.rake +0 -25
  72. data/generators/airbrake/templates/capistrano_hook.rb +0 -6
  73. data/generators/airbrake/templates/initializer.rb +0 -4
  74. data/install.rb +0 -1
  75. data/lib/airbrake/backtrace.rb +0 -103
  76. data/lib/airbrake/capistrano.rb +0 -103
  77. data/lib/airbrake/capistrano3.rb +0 -3
  78. data/lib/airbrake/cli/client.rb +0 -76
  79. data/lib/airbrake/cli/options.rb +0 -45
  80. data/lib/airbrake/cli/printer.rb +0 -33
  81. data/lib/airbrake/cli/project.rb +0 -17
  82. data/lib/airbrake/cli/project_factory.rb +0 -33
  83. data/lib/airbrake/cli/runner.rb +0 -49
  84. data/lib/airbrake/cli/validator.rb +0 -8
  85. data/lib/airbrake/configuration.rb +0 -366
  86. data/lib/airbrake/jobs/send_job.rb +0 -7
  87. data/lib/airbrake/notice.rb +0 -411
  88. data/lib/airbrake/rack.rb +0 -64
  89. data/lib/airbrake/rails.rb +0 -45
  90. data/lib/airbrake/rails/action_controller_catcher.rb +0 -32
  91. data/lib/airbrake/rails/controller_methods.rb +0 -146
  92. data/lib/airbrake/rails/error_lookup.rb +0 -35
  93. data/lib/airbrake/rails/middleware.rb +0 -63
  94. data/lib/airbrake/rails3_tasks.rb +0 -126
  95. data/lib/airbrake/railtie.rb +0 -46
  96. data/lib/airbrake/rake_handler.rb +0 -75
  97. data/lib/airbrake/response.rb +0 -29
  98. data/lib/airbrake/sender.rb +0 -213
  99. data/lib/airbrake/shared_tasks.rb +0 -59
  100. data/lib/airbrake/sidekiq.rb +0 -8
  101. data/lib/airbrake/sinatra.rb +0 -40
  102. data/lib/airbrake/tasks.rb +0 -81
  103. data/lib/airbrake/tasks/airbrake.cap +0 -28
  104. data/lib/airbrake/user_informer.rb +0 -36
  105. data/lib/airbrake/utils/params_cleaner.rb +0 -141
  106. data/lib/airbrake/utils/rack_filters.rb +0 -45
  107. data/lib/airbrake_tasks.rb +0 -62
  108. data/lib/rails/generators/airbrake/airbrake_generator.rb +0 -155
  109. data/lib/templates/rescue.erb +0 -91
  110. data/rails/init.rb +0 -1
  111. data/resources/README.md +0 -34
  112. data/resources/airbrake_2_4.xsd +0 -89
  113. data/resources/airbrake_3_0.json +0 -52
  114. data/resources/ca-bundle.crt +0 -3376
  115. data/script/integration_test.rb +0 -35
  116. data/test/airbrake_tasks_test.rb +0 -161
  117. data/test/backtrace_test.rb +0 -215
  118. data/test/capistrano_test.rb +0 -44
  119. data/test/configuration_test.rb +0 -303
  120. data/test/controller_methods_test.rb +0 -230
  121. data/test/helper.rb +0 -233
  122. data/test/integration.rb +0 -13
  123. data/test/integration/catcher_test.rb +0 -371
  124. data/test/logger_test.rb +0 -79
  125. data/test/notice_test.rb +0 -494
  126. data/test/notifier_test.rb +0 -288
  127. data/test/params_cleaner_test.rb +0 -204
  128. data/test/rack_test.rb +0 -62
  129. data/test/rails_initializer_test.rb +0 -36
  130. data/test/recursion_test.rb +0 -10
  131. data/test/response_test.rb +0 -18
  132. data/test/sender_test.rb +0 -335
  133. data/test/support/response_shim.xml +0 -4
  134. data/test/user_informer_test.rb +0 -29
@@ -0,0 +1,12 @@
1
+ class DummyApp < Sinatra::Base
2
+ use Airbrake::Rack::Middleware
3
+ use Warden::Manager
4
+
5
+ get '/' do
6
+ 'Hello from index'
7
+ end
8
+
9
+ get '/crash' do
10
+ raise AirbrakeTestError
11
+ end
12
+ end
@@ -0,0 +1,17 @@
1
+ require 'spec_helper'
2
+ require 'integration/shared_examples/rack_examples'
3
+
4
+ RSpec.describe "Rack integration specs" do
5
+ let(:app) { DummyApp }
6
+
7
+ include_examples 'rack examples'
8
+
9
+ describe "context payload" do
10
+ it "includes version" do
11
+ get '/crash'
12
+ wait_for_a_request_with_body(
13
+ /"context":{.*"version":"1.2.3 Rack\.version.+Rack\.release/
14
+ )
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,135 @@
1
+ require 'spec_helper'
2
+ require 'integration/shared_examples/rack_examples'
3
+
4
+ RSpec.describe "Rails integration specs" do
5
+ include Warden::Test::Helpers
6
+
7
+ let(:app) { Rails.application }
8
+
9
+ include_examples 'rack examples'
10
+
11
+ it "inserts the Airbrake Rack middleware after DebugExceptions" do
12
+ middlewares = Rails.configuration.middleware.middlewares.map(&:inspect)
13
+ own_idx = middlewares.index('Airbrake::Rack::Middleware')
14
+
15
+ expect(middlewares[own_idx - 1]).to eq('ActionDispatch::DebugExceptions')
16
+ end
17
+
18
+ shared_examples 'context payload content' do |route|
19
+ before do
20
+ login_as(OpenStruct.new(id: 1, email: 'qa@example.com', username: 'qa-dept'))
21
+ get(route, foo: :bar)
22
+ end
23
+
24
+ it "includes component information" do
25
+ wait_for_a_request_with_body(/"context":{.*"component":"dummy".*}/)
26
+ end
27
+
28
+ it "includes action information" do
29
+ case route
30
+ when '/crash'
31
+ wait_for_a_request_with_body(/"context":{.*"action":"crash".*}/)
32
+ when '/notify_airbrake_helper'
33
+ wait_for_a_request_with_body(
34
+ /"context":{.*"action":"notify_airbrake_helper".*}/
35
+ )
36
+ when '/notify_airbrake_sync_helper'
37
+ wait_for_a_request_with_body(
38
+ /"context":{.*"action":"notify_airbrake_sync_helper".*}/
39
+ )
40
+ else
41
+ raise 'Unknown route'
42
+ end
43
+ end
44
+
45
+ it "includes version" do
46
+ wait_for_a_request_with_body(/"context":{.*"version":"1.2.3 Rails/)
47
+ end
48
+
49
+ it "includes session" do
50
+ wait_for_a_request_with_body(
51
+ /"context":{.*"session":{.*"session_id":"\w+".*}/
52
+ )
53
+ end
54
+
55
+ it "includes params" do
56
+ action = route[1..-1]
57
+ wait_for_a_request_with_body(
58
+ /"context":{.*"params":{.*"controller":"dummy","action":"#{action}".*}/
59
+ )
60
+ end
61
+ end
62
+
63
+ describe "context payload" do
64
+ context "when exception reported through middleware" do
65
+ include_examples('context payload content', '/crash')
66
+ end
67
+
68
+ context "when exception reported through the notify_airbrake helper" do
69
+ include_examples('context payload content', '/notify_airbrake_helper')
70
+ end
71
+
72
+ context "when exception reported through the notify_airbrake_sync helper" do
73
+ include_examples('context payload content', '/notify_airbrake_sync_helper')
74
+ end
75
+ end
76
+
77
+ describe "Active Record callbacks" do
78
+ it "reports exceptions in after_commit callbacks" do
79
+ get '/active_record_after_commit'
80
+ wait_for_a_request_with_body(
81
+ /"type":"AirbrakeTestError","message":"after_commit"/
82
+ )
83
+ end
84
+
85
+ it "reports exceptions in after_rollback callbacks" do
86
+ get '/active_record_after_rollback'
87
+ wait_for_a_request_with_body(
88
+ /"type":"AirbrakeTestError","message":"after_rollback"/
89
+ )
90
+ end
91
+ end
92
+
93
+ if Gem::Version.new(Rails.version) >= Gem::Version.new('4.2')
94
+ describe "ActiveJob jobs" do
95
+ it "reports exceptions occurring in ActiveJob workers" do
96
+ get '/active_job'
97
+ sleep 2
98
+
99
+ wait_for(
100
+ a_request(:post, endpoint).
101
+ with(body: /"message":"active_job error"/)
102
+ ).to have_been_made.twice
103
+ end
104
+ end
105
+ end
106
+
107
+ describe "Resque workers" do
108
+ it "reports exceptions occurring in Resque workers" do
109
+ with_resque { get '/resque' }
110
+
111
+ wait_for_a_request_with_body(
112
+ /"message":"resque\serror".*"params":{.*
113
+ "class":"BingoWorker","args":\["bango","bongo"\].*}/x
114
+ )
115
+ end
116
+ end
117
+
118
+ describe "DelayedJob jobs" do
119
+ it "reports exceptions occurring in DelayedJob jobs" do
120
+ get '/delayed_job'
121
+ sleep 2
122
+
123
+ wait_for_a_request_with_body(
124
+ %r("message":"delayed_job\serror".*"params":{.*
125
+ "handler":"---\s!ruby/struct:BangoJob\\nbingo:\s
126
+ bingo\\nbongo:\sbongo\\n".*})x
127
+ )
128
+
129
+ # Two requests are performed during this example. We care only about one.
130
+ # Sleep guarantees that we let the unimportant request occur here and not
131
+ # elsewhere.
132
+ sleep 2
133
+ end
134
+ end
135
+ end
@@ -0,0 +1,160 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe "Rake integration" do
4
+ let(:endpoint) do
5
+ 'https://airbrake.io/api/v3/projects/113743/notices?key=fd04e13d806a90f96614ad8e529b2822'
6
+ end
7
+
8
+ def wait_for_a_request_with_body(body)
9
+ wait_for(a_request(:post, endpoint).with(body: body)).to have_been_made.once
10
+ end
11
+
12
+ def expect_no_requests_with_body(body)
13
+ sleep 1
14
+ expect(a_request(:post, endpoint).with(body: body)).not_to have_been_made
15
+ end
16
+
17
+ before do
18
+ Rails.application.load_tasks
19
+ stub_request(:post, endpoint).to_return(status: 201, body: '{}')
20
+ expect { faulty_task.invoke }.to raise_error(AirbrakeTestError)
21
+ end
22
+
23
+ after do
24
+ # Rake ensures that each task is executed only once per session. For testing
25
+ # purposes, we run the task multiple times.
26
+ faulty_task.reenable
27
+ end
28
+
29
+ describe "a task with maximum information, which raises an exception" do
30
+ let(:faulty_task) { Rake::Task['bingo:bango'] }
31
+
32
+ it "sends the exception to Airbrake" do
33
+ wait_for_a_request_with_body(/"errors":\[{"type":"AirbrakeTestError"/)
34
+ end
35
+
36
+ describe "contains the context payload, which" do
37
+ it "includes correct component" do
38
+ wait_for_a_request_with_body(/"context":{.*"component":"rake".*}/)
39
+ end
40
+
41
+ it "includes correct action" do
42
+ wait_for_a_request_with_body(
43
+ /"context":{.*"action":"bingo:bango".*/
44
+ )
45
+ end
46
+ end
47
+
48
+ describe "contains the params payload, which" do
49
+ it "includes a task name" do
50
+ wait_for_a_request_with_body(
51
+ /"params":{.*"rake_task":{.*"name":"bingo:bango".*}.*}/
52
+ )
53
+ end
54
+
55
+ it "includes a timestamp" do
56
+ wait_for_a_request_with_body(
57
+ /"params":{.*"rake_task":{.*"timestamp":"201\d\-\d\d-\d\d.+".*}.*}/
58
+ )
59
+ end
60
+
61
+ it "includes investigation" do
62
+ # rubocop:disable Metrics/LineLength
63
+ wait_for_a_request_with_body(
64
+ /"params":{.*"rake_task":{.*"investigation":".+Investigating bingo:bango.+".*}.*}/
65
+ )
66
+ # rubocop:enable Metrics/LineLength
67
+ end
68
+
69
+ it "includes full comment" do
70
+ wait_for_a_request_with_body(
71
+ /"params":{.*"rake_task":{.*"full_comment":"Dummy description".*}.*}/
72
+ )
73
+ end
74
+
75
+ it "includes arg names" do
76
+ wait_for_a_request_with_body(
77
+ /"params":{.*"rake_task":{.*"arg_names":\["dummy_arg"\].*}.*}/
78
+ )
79
+ end
80
+
81
+ it "includes arg description" do
82
+ wait_for_a_request_with_body(
83
+ /"params":{.*"rake_task":{.*"arg_description":"\[dummy_arg\]".*}.*}/
84
+ )
85
+ end
86
+
87
+ it "includes locations" do
88
+ # rubocop:disable Metrics/LineLength
89
+ wait_for_a_request_with_body(
90
+ %r("params":{.*"rake_task":{.*"locations":\[".+spec/apps/rails/dummy_task.rake:\d+:in.+"\].*}.*})
91
+ )
92
+ # rubocop:enable Metrics/LineLength
93
+ end
94
+
95
+ it "includes sources" do
96
+ wait_for_a_request_with_body(
97
+ /"params":{.*"rake_task":{.*"sources":\["environment"\].*}.*}/
98
+ )
99
+ end
100
+
101
+ it "includes prerequisite tasks" do
102
+ # rubocop:disable Metrics/LineLength
103
+ wait_for_a_request_with_body(
104
+ /"params":{.*"rake_task":{.*"prerequisite_tasks":\[{"name":"bingo:environment".+\].*}.*}/
105
+ )
106
+ # rubocop:enable Metrics/LineLength
107
+ end
108
+
109
+ it "includes argv info" do
110
+ wait_for_a_request_with_body(
111
+ %r("params":{.*"argv":"--pattern spec/integration/rails/\*_spec.rb".*})
112
+ )
113
+ end
114
+
115
+ it "includes #execute args" do
116
+ wait_for_a_request_with_body(
117
+ /"params":{.*"execute_args":\[\].*}/
118
+ )
119
+ end
120
+ end
121
+ end
122
+
123
+ describe "a task with minimum information, which raises an exception" do
124
+ let(:faulty_task) { Rake::Task['bingo:bongo'] }
125
+
126
+ describe "doesn't contain in the params payload" do
127
+ it "full comment" do
128
+ expect_no_requests_with_body(
129
+ /"params":{.*"rake_task":{.*"full_comment":"Dummy description".*}.*}/
130
+ )
131
+ end
132
+
133
+ it "arg names" do
134
+ expect_no_requests_with_body(
135
+ /"params":{.*"rake_task":{.*"arg_names":\["dummy_arg"\].*}.*}/
136
+ )
137
+ end
138
+
139
+ it "arg description" do
140
+ expect_no_requests_with_body(
141
+ /"params":{.*"rake_task":{.*"arg_description":"\[dummy_arg\]".*}.*}/
142
+ )
143
+ end
144
+
145
+ it "sources" do
146
+ expect_no_requests_with_body(
147
+ /"params":{.*"rake_task":{.*"sources":\["environment"\].*}.*}/
148
+ )
149
+ end
150
+
151
+ it "prerequisite tasks" do
152
+ # rubocop:disable Metrics/LineLength
153
+ expect_no_requests_with_body(
154
+ /"params":{.*"rake_task":{.*"prerequisite_tasks":\[{"name":"bingo:environment".+\].*}.*}/
155
+ )
156
+ # rubocop:enable Metrics/LineLength
157
+ end
158
+ end
159
+ end
160
+ end
@@ -0,0 +1,106 @@
1
+ RSpec.shared_examples 'rack examples' do
2
+ include Warden::Test::Helpers
3
+
4
+ after { Warden.test_reset! }
5
+
6
+ let(:endpoint) do
7
+ 'https://airbrake.io/api/v3/projects/113743/notices?key=fd04e13d806a90f96614ad8e529b2822'
8
+ end
9
+
10
+ def wait_for_a_request_with_body(body)
11
+ wait_for(a_request(:post, endpoint).with(body: body)).to have_been_made.once
12
+ end
13
+
14
+ before do
15
+ stub_request(:post, endpoint).to_return(status: 201, body: '{}')
16
+ end
17
+
18
+ describe "application routes" do
19
+ describe "/index" do
20
+ it "successfully returns 200 and body" do
21
+ get '/'
22
+
23
+ expect(last_response.status).to eq(200)
24
+ expect(last_response.body).to eq('Hello from index')
25
+
26
+ wait_for(a_request(:post, endpoint)).not_to have_been_made
27
+ end
28
+ end
29
+
30
+ describe "/crash" do
31
+ it "returns 500 and sends a notice to Airbrake" do
32
+ get '/crash'
33
+
34
+ expect(last_response.status).to eq(500)
35
+ wait_for_a_request_with_body(/"errors":\[{"type":"AirbrakeTestError"/)
36
+ end
37
+ end
38
+ end
39
+
40
+ describe "context payload" do
41
+ context "when the user is present" do
42
+ let(:common_user_params) do
43
+ { id: 1, email: 'qa@example.com', username: 'qa-dept' }
44
+ end
45
+
46
+ before do
47
+ login_as(OpenStruct.new(user_params))
48
+ get '/crash'
49
+ end
50
+
51
+ context "when the user has first and last names" do
52
+ let(:user_params) do
53
+ common_user_params.merge(first_name: 'Bingo', last_name: 'Bongo')
54
+ end
55
+
56
+ it "reports the user's first and last names" do
57
+ wait_for_a_request_with_body(/
58
+ "context":{.*
59
+ "user":{
60
+ "id":"1",
61
+ "name":"Bingo\sBongo",
62
+ "username":"qa-dept",
63
+ "email":"qa@example.com"}
64
+ /x)
65
+ end
66
+ end
67
+
68
+ context "when the user has only name" do
69
+ let(:user_params) do
70
+ common_user_params.merge(name: 'Bingo')
71
+ end
72
+
73
+ it "reports the user's name" do
74
+ wait_for_a_request_with_body(/
75
+ "context":{.*
76
+ "user":{
77
+ "id":"1",
78
+ "name":"Bingo",
79
+ "username":"qa-dept",
80
+ "email":"qa@example.com"}
81
+ /x)
82
+ end
83
+ end
84
+ end
85
+
86
+ context "when additional parameters present" do
87
+ before do
88
+ get '/crash', nil, 'HTTP_USER_AGENT' => 'Bot'
89
+ end
90
+
91
+ it "features url" do
92
+ wait_for_a_request_with_body(
93
+ %r("context":{.*"url":"http://example\.org/crash".*})
94
+ )
95
+ end
96
+
97
+ it "features hostname" do
98
+ wait_for_a_request_with_body(/"context":{.*"hostname":".+".*}/)
99
+ end
100
+
101
+ it "features userAgent" do
102
+ wait_for_a_request_with_body(/"context":{.*"userAgent":"Bot".*}/)
103
+ end
104
+ end
105
+ end
106
+ end
@@ -0,0 +1,15 @@
1
+ require 'spec_helper'
2
+ require 'integration/shared_examples/rack_examples'
3
+
4
+ RSpec.describe "Sinatra integration specs" do
5
+ let(:app) { DummyApp }
6
+
7
+ include_examples 'rack examples'
8
+
9
+ describe "context payload" do
10
+ it "includes version" do
11
+ get '/crash'
12
+ wait_for_a_request_with_body(/"context":{.*"version":"1.2.3 Sinatra/)
13
+ end
14
+ end
15
+ end