honeybadger 1.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 (65) hide show
  1. data/Gemfile +13 -0
  2. data/Gemfile.lock +114 -0
  3. data/Guardfile +5 -0
  4. data/MIT-LICENSE +22 -0
  5. data/README.md +271 -0
  6. data/Rakefile +261 -0
  7. data/SUPPORTED_RAILS_VERSIONS +26 -0
  8. data/TESTING.md +33 -0
  9. data/features/metal.feature +18 -0
  10. data/features/rack.feature +56 -0
  11. data/features/rails.feature +211 -0
  12. data/features/rake.feature +27 -0
  13. data/features/sinatra.feature +29 -0
  14. data/features/step_definitions/file_steps.rb +10 -0
  15. data/features/step_definitions/metal_steps.rb +23 -0
  16. data/features/step_definitions/rack_steps.rb +23 -0
  17. data/features/step_definitions/rails_application_steps.rb +394 -0
  18. data/features/step_definitions/rake_steps.rb +17 -0
  19. data/features/support/env.rb +17 -0
  20. data/features/support/honeybadger_shim.rb.template +8 -0
  21. data/features/support/rails.rb +201 -0
  22. data/features/support/rake/Rakefile +68 -0
  23. data/features/support/terminal.rb +107 -0
  24. data/generators/honeybadger/honeybadger_generator.rb +94 -0
  25. data/generators/honeybadger/lib/insert_commands.rb +34 -0
  26. data/generators/honeybadger/lib/rake_commands.rb +24 -0
  27. data/generators/honeybadger/templates/capistrano_hook.rb +6 -0
  28. data/generators/honeybadger/templates/honeybadger_tasks.rake +25 -0
  29. data/generators/honeybadger/templates/initializer.rb +6 -0
  30. data/honeybadger.gemspec +109 -0
  31. data/lib/honeybadger.rb +162 -0
  32. data/lib/honeybadger/backtrace.rb +123 -0
  33. data/lib/honeybadger/capistrano.rb +43 -0
  34. data/lib/honeybadger/configuration.rb +273 -0
  35. data/lib/honeybadger/notice.rb +314 -0
  36. data/lib/honeybadger/rack.rb +55 -0
  37. data/lib/honeybadger/rails.rb +34 -0
  38. data/lib/honeybadger/rails/action_controller_catcher.rb +30 -0
  39. data/lib/honeybadger/rails/controller_methods.rb +69 -0
  40. data/lib/honeybadger/rails/middleware/exceptions_catcher.rb +29 -0
  41. data/lib/honeybadger/rails3_tasks.rb +84 -0
  42. data/lib/honeybadger/railtie.rb +45 -0
  43. data/lib/honeybadger/rake_handler.rb +65 -0
  44. data/lib/honeybadger/sender.rb +120 -0
  45. data/lib/honeybadger/shared_tasks.rb +36 -0
  46. data/lib/honeybadger/tasks.rb +82 -0
  47. data/lib/honeybadger_tasks.rb +65 -0
  48. data/lib/rails/generators/honeybadger/honeybadger_generator.rb +99 -0
  49. data/rails/init.rb +1 -0
  50. data/resources/README.md +34 -0
  51. data/resources/ca-bundle.crt +3376 -0
  52. data/script/integration_test.rb +38 -0
  53. data/test/test_helper.rb +143 -0
  54. data/test/unit/backtrace_test.rb +180 -0
  55. data/test/unit/capistrano_test.rb +34 -0
  56. data/test/unit/configuration_test.rb +201 -0
  57. data/test/unit/honeybadger_tasks_test.rb +163 -0
  58. data/test/unit/logger_test.rb +72 -0
  59. data/test/unit/notice_test.rb +406 -0
  60. data/test/unit/notifier_test.rb +245 -0
  61. data/test/unit/rack_test.rb +56 -0
  62. data/test/unit/rails/action_controller_catcher_test.rb +300 -0
  63. data/test/unit/rails_test.rb +35 -0
  64. data/test/unit/sender_test.rb +257 -0
  65. metadata +315 -0
@@ -0,0 +1,26 @@
1
+ 2.3.14
2
+ 3.0.0
3
+ 3.0.1
4
+ 3.0.2
5
+ 3.0.3
6
+ 3.0.4
7
+ 3.0.5
8
+ 3.0.6
9
+ 3.0.7
10
+ 3.0.8
11
+ 3.0.9
12
+ 3.0.10
13
+ 3.0.11
14
+ 3.0.12
15
+ 3.1.0
16
+ 3.1.1
17
+ 3.1.2
18
+ 3.1.3
19
+ 3.1.4
20
+ 3.2.0
21
+ 3.2.1
22
+ 3.2.2
23
+ 3.2.3
24
+ 3.2.4
25
+ 3.2.5
26
+ 3.2.6
data/TESTING.md ADDED
@@ -0,0 +1,33 @@
1
+ Running the suite
2
+ =================
3
+
4
+ Since the notifier must run on many versions of Rails, running its test suite is slightly different than you may be used to.
5
+
6
+ You should start by trusting the .rvmrc file. We come in peace.
7
+
8
+ Then execute the following command:
9
+
10
+ rake vendor_test_gems
11
+ # NOT: bundle exec rake vendor_test_gems
12
+
13
+ This command will download the various versions of Rails and other gems that the notifier must be tested against.
14
+
15
+ Then, to start the suite, run
16
+
17
+ rake
18
+ # NOT: bundle exec rake
19
+
20
+ Finally, this test suite runs against many rails versions. If you
21
+ prefer to run it against specific version hit
22
+
23
+ rake cucumber:rails:<VERSION>
24
+
25
+
26
+ For Maintainers
27
+ ================
28
+
29
+ When developing the Honeybadger gem, be sure to use the integration test against an existing project on staging before pushing to master.
30
+
31
+ ./script/integration_test.rb <test project's api key> <staging server hostname>
32
+
33
+ ./script/integration_test.rb <test project's api key> <staging server hostname> secure
@@ -0,0 +1,18 @@
1
+ Feature: Rescue errors in Rails middleware
2
+
3
+ Background:
4
+ Given I have built and installed the "honeybadger" gem
5
+ And I generate a new Rails application
6
+ And I configure the Honeybadger shim
7
+ And I configure my application to require the "honeybadger" gem
8
+ And I run the honeybadger generator with "-k myapikey"
9
+
10
+ Scenario: Rescue an exception in the dispatcher
11
+ When I define a Metal endpoint called "Exploder":
12
+ """
13
+ def self.call(env)
14
+ raise "Explode"
15
+ end
16
+ """
17
+ When I perform a request to "http://example.com:123/metal/index?param=value"
18
+ Then I should receive a Honeybadger notification
@@ -0,0 +1,56 @@
1
+ Feature: Use the notifier in a plain Rack app
2
+
3
+ Background:
4
+ Given I have built and installed the "honeybadger" gem
5
+
6
+ Scenario: Rescue and exception in a Rack app
7
+ Given the following Rack app:
8
+ """
9
+ require 'rack'
10
+ require 'honeybadger'
11
+
12
+ Honeybadger.configure do |config|
13
+ config.api_key = 'my_api_key'
14
+ end
15
+
16
+ app = Rack::Builder.app do
17
+ use Honeybadger::Rack
18
+ run lambda { |env| raise "Rack down" }
19
+ end
20
+ """
21
+ When I perform a Rack request to "http://example.com:123/test/index?param=value"
22
+ Then I should receive a Honeybadger notification
23
+
24
+ Scenario: Ignore user agents
25
+ Given the following Rack app:
26
+ """
27
+ require 'rack'
28
+ require 'honeybadger'
29
+
30
+ Honeybadger.configure do |config|
31
+ config.api_key = 'my_api_key'
32
+ config.ignore_user_agent << /ignore/
33
+ end
34
+
35
+ class Mock
36
+ class AppendUserAgent
37
+ def initialize(app)
38
+ @app = app
39
+ end
40
+
41
+ def call(env)
42
+ env["HTTP_USER_AGENT"] = "ignore"
43
+ @app.call(env)
44
+ end
45
+ end
46
+ end
47
+
48
+ app = Rack::Builder.app do
49
+ use Honeybadger::Rack
50
+ use Mock::AppendUserAgent
51
+ run lambda { |env| raise "Rack down" }
52
+ end
53
+ """
54
+ When I perform a Rack request to "http://example.com:123/test/index?param=value"
55
+ Then I should not see "** [Honeybadger] Response from Honeybadger:"
56
+
@@ -0,0 +1,211 @@
1
+ Feature: Install the Gem in a Rails application
2
+
3
+ Background:
4
+ Given I have built and installed the "honeybadger" gem
5
+ And I generate a new Rails application
6
+
7
+ Scenario: Use the gem without vendoring the gem in a Rails application
8
+ When I configure the Honeybadger shim
9
+ And I configure my application to require the "honeybadger" gem
10
+ And I run the honeybadger generator with "-k myapikey"
11
+ Then the command should have run successfully
12
+ And I should receive a Honeybadger notification
13
+ And I should see the Rails version
14
+
15
+ Scenario: vendor the gem and uninstall
16
+ When I configure the Honeybadger shim
17
+ And I configure my application to require the "honeybadger" gem
18
+ And I unpack the "honeybadger" gem
19
+ And I run the honeybadger generator with "-k myapikey"
20
+ Then the command should have run successfully
21
+ When I uninstall the "honeybadger" gem
22
+ And I install cached gems
23
+ And I run "rake honeybadger:test"
24
+ Then I should see "** [Honeybadger] Response from Honeybadger:"
25
+ And I should receive two Honeybadger notifications
26
+
27
+ Scenario: Configure the notifier by hand
28
+ When I configure the Honeybadger shim
29
+ And I configure the notifier to use "myapikey" as an API key
30
+ And I configure my application to require the "honeybadger" gem
31
+ And I run the honeybadger generator with ""
32
+ Then I should receive a Honeybadger notification
33
+
34
+ Scenario: Configuration within initializer isn't overridden by Railtie
35
+ When I configure the Honeybadger shim
36
+ And I configure usage of Honeybadger
37
+ Then the command should have run successfully
38
+ When I configure the notifier to use the following configuration lines:
39
+ """
40
+ config.api_key = "myapikey"
41
+ config.project_root = "argle/bargle"
42
+ """
43
+ And I define a response for "TestController#index":
44
+ """
45
+ session[:value] = "test"
46
+ raise RuntimeError, "some message"
47
+ """
48
+ And I route "/test/index" to "test#index"
49
+ And I perform a request to "http://example.com:123/test/index?param=value"
50
+ Then I should receive a Honeybadger notification
51
+
52
+ Scenario: Try to install without an api key
53
+ When I configure my application to require the "honeybadger" gem
54
+ And I run the honeybadger generator with ""
55
+ Then I should see "Must pass --api-key or --heroku or create config/initializers/honeybadger.rb"
56
+
57
+ Scenario: Configure and deploy using only installed gem
58
+ When I run "capify ."
59
+ And I configure the Honeybadger shim
60
+ And I configure my application to require the "honeybadger" gem
61
+ And I run the honeybadger generator with "-k myapikey"
62
+ And I configure my application to require the "capistrano" gem if necessary
63
+ And I run "cap -T"
64
+ Then I should see "honeybadger:deploy"
65
+
66
+ Scenario: Configure and deploy using only vendored gem
67
+ When I run "capify ."
68
+ And I configure the Honeybadger shim
69
+ And I configure my application to require the "honeybadger" gem
70
+ And I unpack the "honeybadger" gem
71
+ And I run the honeybadger generator with "-k myapikey"
72
+ And I uninstall the "honeybadger" gem
73
+ And I install cached gems
74
+ And I configure my application to require the "capistrano" gem if necessary
75
+ And I run "cap -T"
76
+ Then I should see "honeybadger:deploy"
77
+
78
+ Scenario: Try to install when the honeybadger plugin still exists
79
+ When I install the "honeybadger" plugin
80
+ And I configure the Honeybadger shim
81
+ And I configure the notifier to use "myapikey" as an API key
82
+ And I configure my application to require the "honeybadger" gem
83
+ And I run the honeybadger generator with ""
84
+ Then I should see "You must first remove the honeybadger plugin. Please run: script/plugin remove honeybadger"
85
+
86
+ Scenario: Rescue an exception in a controller
87
+ When I configure the Honeybadger shim
88
+ And I configure usage of Honeybadger
89
+ And I define a response for "TestController#index":
90
+ """
91
+ session[:value] = "test"
92
+ raise RuntimeError, "some message"
93
+ """
94
+ And I route "/test/index" to "test#index"
95
+ And I perform a request to "http://example.com:123/test/index?param=value"
96
+ Then I should receive a Honeybadger notification
97
+
98
+ Scenario: The gem should not be considered a framework gem
99
+ When I configure the Honeybadger shim
100
+ And I configure my application to require the "honeybadger" gem
101
+ And I run the honeybadger generator with "-k myapikey"
102
+ And I run "rake gems"
103
+ Then I should see that "honeybadger" is not considered a framework gem
104
+
105
+ Scenario: The app uses Vlad instead of Capistrano
106
+ When I configure the Honeybadger shim
107
+ And I configure my application to require the "honeybadger" gem
108
+ And I run "touch config/deploy.rb"
109
+ And I run "rm Capfile"
110
+ And I run the honeybadger generator with "-k myapikey"
111
+ Then "config/deploy.rb" should not contain "capistrano"
112
+
113
+ Scenario: Support the Heroku addon in the generator
114
+ When I configure the Honeybadger shim
115
+ And I configure the Heroku rake shim
116
+ And I configure the Heroku gem shim with "myapikey"
117
+ And I configure my application to require the "honeybadger" gem
118
+ And I run the honeybadger generator with "--heroku"
119
+ Then the command should have run successfully
120
+ And I should receive a Honeybadger notification
121
+ And I should see the Rails version
122
+ And my Honeybadger configuration should contain the following line:
123
+ """
124
+ config.api_key = ENV['HONEYBADGER_API_KEY']
125
+ """
126
+
127
+ Scenario: Support the --app option for the Heroku addon in the generator
128
+ When I configure the Honeybadger shim
129
+ And I configure the Heroku rake shim
130
+ And I configure the Heroku gem shim with "myapikey" and multiple app support
131
+ And I configure my application to require the "honeybadger" gem
132
+ And I run the honeybadger generator with "--heroku -a myapp"
133
+ Then the command should have run successfully
134
+ And I should receive a Honeybadger notification
135
+ And I should see the Rails version
136
+ And my Honeybadger configuration should contain the following line:
137
+ """
138
+ config.api_key = ENV['HONEYBADGER_API_KEY']
139
+ """
140
+
141
+ Scenario: Filtering parameters in a controller
142
+ When I configure the Honeybadger shim
143
+ And I configure usage of Honeybadger
144
+ When I configure the notifier to use the following configuration lines:
145
+ """
146
+ config.api_key = "myapikey"
147
+ config.params_filters << "credit_card_number"
148
+ """
149
+ And I define a response for "TestController#index":
150
+ """
151
+ params[:credit_card_number] = "red23"
152
+ raise RuntimeError, "some message"
153
+ """
154
+ And I route "/test/index" to "test#index"
155
+ And I perform a request to "http://example.com:123/test/index?param=value"
156
+ Then I should receive a Honeybadger notification
157
+
158
+ Scenario: Filtering session in a controller
159
+ When I configure the Honeybadger shim
160
+ And I configure usage of Honeybadger
161
+ When I configure the notifier to use the following configuration lines:
162
+ """
163
+ config.api_key = "myapikey"
164
+ config.params_filters << "secret"
165
+ """
166
+ And I define a response for "TestController#index":
167
+ """
168
+ session["secret"] = "blue42"
169
+ raise RuntimeError, "some message"
170
+ """
171
+ And I route "/test/index" to "test#index"
172
+ And I perform a request to "http://example.com:123/test/index?param=value"
173
+ Then I should receive a Honeybadger notification
174
+
175
+ Scenario: Filtering session and params based on Rails parameter filters
176
+ When I configure the Honeybadger shim
177
+ And I configure usage of Honeybadger
178
+ And I configure the application to filter parameter "secret"
179
+ And I define a response for "TestController#index":
180
+ """
181
+ params["secret"] = "red23"
182
+ session["secret"] = "blue42"
183
+ raise RuntimeError, "some message"
184
+ """
185
+ And I route "/test/index" to "test#index"
186
+ And I perform a request to "http://example.com:123/test/index?param=value"
187
+ Then I should receive a Honeybadger notification
188
+
189
+ Scenario: Notify honeybadger within the controller
190
+ When I configure the Honeybadger shim
191
+ And I configure usage of Honeybadger
192
+ And I define a response for "TestController#index":
193
+ """
194
+ session[:value] = "test"
195
+ notify_honeybadger(RuntimeError.new("some message"))
196
+ render :nothing => true
197
+ """
198
+ And I route "/test/index" to "test#index"
199
+ And I perform a request to "http://example.com:123/test/index?param=value"
200
+ Then I should receive a Honeybadger notification
201
+
202
+ Scenario: Reporting 404s
203
+ When I configure the Honeybadger shim
204
+ And I configure usage of Honeybadger
205
+ And I configure the notifier to use the following configuration lines:
206
+ """
207
+ config.ignore_only = []
208
+ """
209
+ And I perform a request to "http://example.com:123/this/route/does/not/exist"
210
+ Then I should see "The page you were looking for doesn't exist."
211
+ And I should receive a Honeybadger notification
@@ -0,0 +1,27 @@
1
+ Feature: Use the Gem to catch errors in a Rake application
2
+ Background:
3
+ Given I have built and installed the "honeybadger" gem
4
+
5
+ Scenario: Catching exceptions in Rake
6
+ When I run rake with honeybadger
7
+ Then Honeybadger should catch the exception
8
+
9
+ Scenario: Falling back to default handler before Honeybadger is configured
10
+ When I run rake with honeybadger not yet configured
11
+ Then Honeybadger should not catch the exception
12
+
13
+ Scenario: Disabling Rake exception catcher
14
+ When I run rake with honeybadger disabled
15
+ Then Honeybadger should not catch the exception
16
+
17
+ Scenario: Autodetect, running from terminal
18
+ When I run rake with honeybadger autodetect from terminal
19
+ Then Honeybadger should not catch the exception
20
+
21
+ Scenario: Autodetect, not running from terminal
22
+ When I run rake with honeybadger autodetect not from terminal
23
+ Then Honeybadger should catch the exception
24
+
25
+ Scenario: Sending the correct component name
26
+ When I run rake with honeybadger
27
+ Then Honeybadger should send the rake command line as the component name
@@ -0,0 +1,29 @@
1
+ Feature: Use the notifier in a Sinatra app
2
+
3
+ Background:
4
+ Given I have built and installed the "honeybadger" gem
5
+
6
+ Scenario: Rescue an exception in a Sinatra app
7
+ Given the following Rack app:
8
+ """
9
+ require 'sinatra/base'
10
+ require 'honeybadger'
11
+
12
+ Honeybadger.configure do |config|
13
+ config.api_key = 'my_api_key'
14
+ end
15
+
16
+ class FontaneApp < Sinatra::Base
17
+ use Honeybadger::Rack
18
+ enable :raise_errors
19
+
20
+ get "/test/index" do
21
+ raise "Sinatra has left the building"
22
+ end
23
+ end
24
+
25
+ app = FontaneApp
26
+ """
27
+ When I perform a Rack request to "http://example.com:123/test/index?param=value"
28
+ Then I should receive a Honeybadger notification
29
+
@@ -0,0 +1,10 @@
1
+ Then /^"([^\"]*)" should not contain text of "([^\"]*)"$/ do |target_file, contents_file|
2
+ notifier_root = File.join(File.dirname(__FILE__), '..', '..')
3
+ full_path_contents = File.join(notifier_root, contents_file)
4
+ contents_text = File.open(full_path_contents).read
5
+
6
+ full_path_target = File.join(rails_root, target_file)
7
+ target_text = File.open(full_path_target).read
8
+
9
+ target_text.should_not include(contents_text)
10
+ end
@@ -0,0 +1,23 @@
1
+ When /^I define a Metal endpoint called "([^\"]*)":$/ do |class_name, definition|
2
+ FileUtils.mkdir_p(File.join(rails_root, 'app', 'metal'))
3
+ file_name = File.join(rails_root, 'app', 'metal', "#{class_name.underscore}.rb")
4
+ File.open(file_name, "w") do |file|
5
+ file.puts "class #{class_name}"
6
+ file.puts definition
7
+ file.puts "end"
8
+ end
9
+ When %{the metal endpoint "#{class_name}" is mounted in the Rails 3 routes.rb} if rails3?
10
+ end
11
+
12
+ When /^the metal endpoint "([^\"]*)" is mounted in the Rails 3 routes.rb$/ do |class_name|
13
+ routesrb = File.join(rails_root, "config", "routes.rb")
14
+ routes = IO.readlines(routesrb)
15
+ rack_route = "match '/metal(/*other)' => #{class_name}"
16
+ routes = routes[0..-2] + [rack_route, routes[-1]]
17
+ File.open(routesrb, "w") do |f|
18
+ f.puts "require 'app/metal/#{class_name.underscore}'"
19
+ routes.each do |route_line|
20
+ f.puts route_line
21
+ end
22
+ end
23
+ end