Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge remote branch 'github/master' into upgrade-to-2-4-5

* github/master: (82 commits)
  Bumping to version 2.4.5
  Add the UserNotifier to the head of the stack, don't require Rack::Lock's presence
  Bumping to version 2.4.4
  Unit test showing escape_javascript is being called on request.url
  Don't misspell don't
  first pass at changing JS html insertion into helper instead
  Bumping to version 2.4.3
  Make the text presented to the user customizable
  Insert the Hoptoad Error Number into the response if possible.
  Fixes the 'has_content?' mission problem.
  thank all contributors
  remove the old rdoc readme
  iconvert readme to markdown and add credit and license info
  some shells dont know about [[
  allow the value sent in to have whitespace around it
  Bumping to version 2.4.2
  fix issue where the gsub to replace the html head with javascript was removing the head element entirely
  Bumping to version 2.4.1
  restore method which may have been accidentally removed?
  Bumping to version 2.4.0
  ...
  • Loading branch information...
commit acb589fe9ee2b9f138b1dfbb8006fa7290f99867 2 parents 0a6a042 + 6ac4404
@tylerkovacs tylerkovacs authored
Showing with 1,228 additions and 372 deletions.
  1. +221 −0 CHANGELOG
  2. +182 −141 README.rdoc → README.md
  3. +93 −0 README_FOR_HEROKU_ADDON.md
  4. +21 −11 Rakefile
  5. +6 −6 SUPPORTED_RAILS_VERSIONS
  6. +2 −2 features/metal.feature
  7. +44 −41 features/rails.feature
  8. +78 −0 features/rails_with_js_notifier.feature
  9. +1 −1  features/sinatra.feature
  10. +13 −0 features/step_definitions/metal_steps.rb
  11. +54 −68 features/step_definitions/rails_application_steps.rb
  12. +9 −1 features/support/hoptoad_shim.rb.template
  13. +3 −1 features/support/matchers.rb
  14. +70 −0 features/support/rails.rb
  15. +13 −1 features/support/terminal.rb
  16. +42 −0 features/user_informer.feature
  17. +26 −1 generators/hoptoad/hoptoad_generator.rb
  18. +7 −2 lib/hoptoad_notifier.rb
  19. +12 −6 lib/hoptoad_notifier/configuration.rb
  20. +9 −1 lib/hoptoad_notifier/notice.rb
  21. +4 −2 lib/hoptoad_notifier/rack.rb
  22. +2 −0  lib/hoptoad_notifier/rails.rb
  23. +2 −1  lib/hoptoad_notifier/rails/action_controller_catcher.rb
  24. +9 −1 lib/hoptoad_notifier/rails/controller_methods.rb
  25. +19 −18 lib/hoptoad_notifier/rails/javascript_notifier.rb
  26. +2 −11 lib/hoptoad_notifier/rails3_tasks.rb
  27. +7 −4 lib/hoptoad_notifier/railtie.rb
  28. +14 −1 lib/hoptoad_notifier/sender.rb
  29. +29 −0 lib/hoptoad_notifier/shared_tasks.rb
  30. +2 −16 lib/hoptoad_notifier/tasks.rb
  31. +29 −0 lib/hoptoad_notifier/user_informer.rb
  32. +1 −1  lib/hoptoad_notifier/version.rb
  33. +25 −0 lib/rails/generators/hoptoad/hoptoad_generator.rb
  34. +13 −6 lib/templates/javascript_notifier.erb
  35. +2 −0  test/catcher_test.rb
  36. +9 −2 test/configuration_test.rb
  37. +10 −1 test/helper.rb
  38. +52 −0 test/javascript_notifier_test.rb
  39. +23 −22 test/notice_test.rb
  40. +39 −3 test/sender_test.rb
  41. +29 −0 test/user_informer_test.rb
View
221 CHANGELOG
@@ -1,3 +1,209 @@
+Version 2.4.5 - Wed Feb 02 13:24:29 -0500 2011
+===============================================================================
+
+Jonathan Yurek (1):
+ Don't require Rack::Lock's presence in the middleware for UserInformer
+
+
+Version 2.4.4 - Fri Jan 28 13:50:10 -0500 2011
+===============================================================================
+
+Matt Jankowski (1):
+ Change the javascript notifier from a config option to a helper method
+
+Jonathan Yurek (1):
+ Show the javascript notifier prevents XSS attempts from request.url
+
+Version 2.4.3 - Wed Jan 26 11:35:15 -0500 2011
+===============================================================================
+
+Jon Yurek (1):
+ Allow the application to present the Hoptoad error number to the user
+
+
+Version 2.4.2 - Sun Jan 09 09:37:31 -0500 2011
+===============================================================================
+
+Matt Jankowski (1):
+ fix issue where the gsub to replace the html head with javascript was removing the head element entirely
+
+
+Version 2.4.1 - Sat Jan 08 12:17:15 -0500 2011
+===============================================================================
+
+Matt Jankowski (1):
+ restore method which may have been accidentally removed?
+
+
+Version 2.4.0 - Thu Jan 06 15:03:58 -0500 2011
+===============================================================================
+
+Jason Morrison (1):
+ Remove official support for very old Rails version going forward
+
+Version 2.3.14 - Wed Jan 05 14:06:12 -0500 2011
+===============================================================================
+
+Jason Morrison (1):
+ Fix 'require' path
+
+Version 2.3.13 - Mon Jan 03 15:56:20 -0500 2011
+===============================================================================
+
+Dan Croak (1):
+ including twiddle wakka in install instructions
+
+Emma Lindsay (5):
+ Sends more javascript information back to hoptaod
+ Merge branch 'js_notifier_default_fields'
+ Bumping to version 2.3.10
+ Updated jferris-mocha to bourne
+ Update readme to show quotes around error names in ignores
+
+Jason Morrison (8):
+ wip: Supply default url, component, action for JS notifier
+ gracefully fall back to require 'activesupport' if require 'active_support' fails
+ Add non-capistrano deploy instructions
+ Add instructions for heroku gem to Heroku addon README
+ Add AbstractController::ActionNotFound to default ignore list
+ Bumping to version 2.3.12
+ Bugfix: JS Notifier will now insert itself even when <head> tag has attributes
+ Add Heroku deploy notification
+
+Jon Yurek (11):
+ Require bourne, run right cucumber task
+ Get the API key from Heroku
+ Bumped version: 2.3.11
+ Getting green cucumber stories
+ Fakes out the heroku command for cucumber.
+ Mount the metal endpoint in Rails 3 tests.
+ Metal test mounts at /metal
+ Supported versions: 2.3.9, 2.3.10, and 3.0.1
+ Return non-zero on cucumber failure.
+ Controller info for older Rails-es is different.
+ Remove Rails 2.0.2 from official support. Added 3.0.2+3
+
+Trevor Turk (1):
+ Fix default ignores in the README
+
+
+Version 2.3.12 - Wed Nov 03 13:53:18 -0400 2010
+===============================================================================
+
+In general: Update gems, improve testing, improve documentation, improve
+javascript notifier.
+
+Emma Lindsay (4):
+ Sends more javascript information back to hoptaod
+ Merge branch 'js_notifier_default_fields'
+ Bumping to version 2.3.10
+ Updated jferris-mocha to bourne
+
+Jason Morrison (5):
+ wip: Supply default url, component, action for JS notifier
+ gracefully fall back to require 'activesupport' if require 'active_support' fails
+ Add non-capistrano deploy instructions
+ Add instructions for heroku gem to Heroku addon README
+ Add AbstractController::ActionNotFound to default ignore list
+
+Jon Yurek (9):
+ Require bourne, run right cucumber task
+ Get the API key from Heroku
+ Bumped version: 2.3.11
+ Getting green cucumber stories
+ Fakes out the heroku command for cucumber.
+ Mount the metal endpoint in Rails 3 tests.
+ Metal test mounts at /metal
+ Supported versions: 2.3.9, 2.3.10, and 3.0.1
+ Return non-zero on cucumber failure.
+
+
+Version 2.3.10 - Mon Oct 18 17:07:56 -0400 2010
+===============================================================================
+
+Emma Lindsay (2):
+ Sends more javascript information back to hoptaod
+ Merge branch 'js_notifier_default_fields'
+
+Jason Morrison (2):
+ wip: Supply default url, component, action for JS notifier
+ gracefully fall back to require 'activesupport' if require 'active_support' fails
+
+
+Version 2.3.9 - 2010-10-18
+===============================================================================
+
+This patch release contains a handful of bugfixes, and ensures:
+ If hoptoadapp.com is completely unreachable by HTTP, your app is not affected.
+ Controller method #notify_hoptoad is available in Rails 3. Thanks contributor Kyle Crum!
+
+Chad Pytel (1):
+ also handle Errno::ECONNREFUSED and other http errors
+
+Jason Morrison (4):
+ Add gem versions to test suite
+ Revert "Revert "attempt to debug mail sending on staging""
+ Adding Heroku notifier readme
+ gracefully fall back to require 'activesupport' if require 'active_support' fails
+
+Jon Yurek (2):
+ Bumping version to 2.3.8
+ Adds builder to the gemspec
+
+Kyle Crum (3):
+ notify_hoptoad now works in rails 3 controllers
+ more sane way of testing for rails 3 controller methods
+ added a scenario for using the notify_hoptoad method within a controller
+
+
+Version 2.3.7 - 2010-09-15
+===============================================================================
+
+Jason Morrison (5):
+ Add ./ prefix to require for 1.9.2
+ More helpful message for testing without ENV['RAILS_VERSION']
+ Support Rails 3.0.0, not 3.0.0.rc
+ This wasn't actually a fix (it regressed tests): Revert "Fix modifying params_filters"
+ Correct the #also_use_rack_params_filters method
+
+Joshua Clayton (1):
+ Fix modifying params_filters
+
+Nick Quaranto (2):
+ s/RSpec/Spec for matchers
+ use Sinatra::Default instead of Sinatra::Base
+
+
+Version 2.3.6 - 2010-08-30
+===============================================================================
+
+Daniel Barron (1):
+ Initializer configuration overrides Railtie configuration if set
+
+Joshua Clayton (1):
+ Remove rack.request.form_vars
+
+Tristan Dunn (1):
+ Move Rails JS scenarios into separate feature and correctly support HTTPS when secure is enabled on the notifier.
+
+
+Version 2.3.5 - 2010-08-13
+===============================================================================
+
+Alexey Palazhchenko (1):
+ Actually call #to_hash.
+
+Joshua Clayton (1):
+ Trace hoptoad:test task when running generator for anything before Rails3
+
+
+Version 2.3.4 - 2010-08-10
+===============================================================================
+
+Tristan Dunn (1):
+ Only include the JS notifier in public environments.
+
+
Version 2.3.3 - 2010-08-04
===============================================================================
@@ -183,3 +389,18 @@ Nick Quaranto (3):
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
View
323 README.rdoc → README.md
@@ -1,96 +1,100 @@
-= HoptoadNotifier
+HoptoadNotifier
+===============
This is the notifier gem for integrating apps with Hoptoad.
When an uncaught exception occurs, HoptoadNotifier will POST the relevant data
to the Hoptoad server specified in your environment.
-== Help
+Help
+----
-* {IRC}[irc://irc.freenode.net/thoughtbot]
-* {mailing list}[http://groups.google.com/group/hoptoad-notifier-dev]
+For help with using Hoptoad and the Hoptoad notifier visit [our support site](http://help.hoptoadapp.com)
-== Rails Installation
+For discussion of Hoptoad notifier development check out the [mailing list](http://groups.google.com/group/hoptoad-notifier-dev)
-=== Remove exception_notifier
+Rails Installation
+------------------
+
+### Remove exception_notifier
in your ApplicationController, REMOVE this line:
- include ExceptionNotifiable
+ include ExceptionNotifiable
In your config/environment* files, remove all references to ExceptionNotifier
Remove the vendor/plugins/exception_notifier directory.
-=== Remove hoptoad_notifier plugin
+### Remove hoptoad_notifier plugin
Remove the vendor/plugins/hoptoad_notifier directory before installing the gem, or run:
- script/plugin remove hoptoad_notifier
+ script/plugin remove hoptoad_notifier
-=== Rails 3.x
+### Rails 3.x
Add the hoptoad_notifier gem to your Gemfile. In Gemfile:
- gem 'hoptoad_notifier'
+ gem "hoptoad_notifier", "~> 2.3"
Then from your project's RAILS_ROOT, run:
- bundle install
- script/rails generate hoptoad --api-key your_key_here
+ bundle install
+ script/rails generate hoptoad --api-key your_key_here
That's it!
-=== Rails 2.x
+### Rails 2.x
Add the hoptoad_notifier gem to your app. In config/environment.rb:
- config.gem 'hoptoad_notifier'
+ config.gem 'hoptoad_notifier'
Then from your project's RAILS_ROOT, run:
- rake gems:install
- rake gems:unpack GEM=hoptoad_notifier
- script/generate hoptoad --api-key your_key_here
+ rake gems:install
+ rake gems:unpack GEM=hoptoad_notifier
+ script/generate hoptoad --api-key your_key_here
As always, if you choose not to vendor the hoptoad_notifier gem, make sure
every server you deploy to has the gem installed or your application won't start.
-=== Rails 1.2.6
+### Rails 1.2.6
Install the hoptoad_notifier gem:
- gem install hoptoad_notifier
+ gem install hoptoad_notifier
Once installed, you should vendor the hoptoad_notifier gem:
- mkdir vendor/gems
- cd vendor/gems
- gem unpack hoptoad_notifier
+ mkdir vendor/gems
+ cd vendor/gems
+ gem unpack hoptoad_notifier
And then add the following to the Rails::Initializer.run do |config|
block in environment.rb so that the vendored gem is loaded.
- # Add the vendor/gems/*/lib directories to the LOAD_PATH
- config.load_paths += Dir.glob(File.join(RAILS_ROOT, 'vendor', 'gems', '*', 'lib'))
+ # Add the vendor/gems/*/lib directories to the LOAD_PATH
+ config.load_paths += Dir.glob(File.join(RAILS_ROOT, 'vendor', 'gems', '*', 'lib'))
Next add something like this at the bottom of your config/environment.rb:
- require 'hoptoad_notifier'
- require 'hoptoad_notifier/rails'
- HoptoadNotifier.configure do |config|
- config.api_key = 'your_key_here'
- end
+ require 'hoptoad_notifier'
+ require 'hoptoad_notifier/rails'
+ HoptoadNotifier.configure do |config|
+ config.api_key = 'your_key_here'
+ end
You will also need to copy the hoptoad_notifier_tasks.rake file into your
RAILS_ROOT/lib/tasks directory in order for the rake hoptoad:test task to work:
- cp vendor/gems/hoptoad_notifier-*/generators/hoptoad/templates/hoptoad_notifier_tasks.rake lib/tasks
+ cp vendor/gems/hoptoad_notifier-*/generators/hoptoad/templates/hoptoad_notifier_tasks.rake lib/tasks
As always, if you choose not to vendor the hoptoad_notifier gem, make sure
every server you deploy to has the gem installed or your application won't start.
-=== Upgrading From Earlier Versions of Hoptoad
+### Upgrading From Earlier Versions of Hoptoad
If you're currently using the plugin version (if you have a
vendor/plugins/hoptoad_notifier directory, you are), you'll need to perform a
@@ -131,7 +135,7 @@ As always, if you choose not to vendor the hoptoad_notifier gem, make sure
every server you deploy to has the gem installed or your application won't
start.
-== Upgrading from Earlier Versions of the Hoptoad Gem (with config.gem)
+### Upgrading from Earlier Versions of the Hoptoad Gem (with config.gem)
If you're currently using the gem version of the hoptoad_notifier and have
a version of Rails that uses config.gem (in the 2.x series), there is
@@ -148,56 +152,59 @@ You can them continue to install normally. If you don't remove the rake file,
you will be unable to unpack this gem (Rails will think it's part of the
framework).
-=== Testing it out
+### Testing it out
You can test that Hoptoad is working in your production environment by using
this rake task (from RAILS_ROOT):
- rake hoptoad:test
+ rake hoptoad:test
If everything is configured properly, that task will send a notice to Hoptoad
which will be visible immediately.
-== Rack
+Rack
+----
In order to use hoptoad_notifier in a non-Rails rack app, just load the
hoptoad_notifier, configure your API key, and use the HoptoadNotifier::Rack
middleware:
- require 'rack'
- require 'hoptoad_notifier'
+ require 'rack'
+ require 'hoptoad_notifier'
- HoptoadNotifier.configure do |config|
- config.api_key = 'my_api_key'
- end
+ HoptoadNotifier.configure do |config|
+ config.api_key = 'my_api_key'
+ end
- app = Rack::Builder.app do
- use HoptoadNotifier::Rack
- run lambda { |env| raise "Rack down" }
- end
+ app = Rack::Builder.app do
+ use HoptoadNotifier::Rack
+ run lambda { |env| raise "Rack down" }
+ end
-== Sinatra
+Sinatra
+-------
Using hoptoad_notifier in a Sinatra app is just like a Rack app, but you have
to disable Sinatra's error rescuing functionality:
- require 'sinatra/base'
- require 'hoptoad_notifier'
-
- HoptoadNotifier.configure do |config|
- config.api_key = 'my_api_key'
- end
-
- class MyApp < Sinatra::Default
- use HoptoadNotifier::Rack
- enable :raise_errors
-
- get "/" do
- raise "Sinatra has left the building"
+ require 'sinatra/base'
+ require 'hoptoad_notifier'
+
+ HoptoadNotifier.configure do |config|
+ config.api_key = 'my_api_key'
+ end
+
+ class MyApp < Sinatra::Default
+ use HoptoadNotifier::Rack
+ enable :raise_errors
+
+ get "/" do
+ raise "Sinatra has left the building"
+ end
end
- end
-== Usage
+Usage
+-----
For the most part, Hoptoad works for itself. Once you've included the notifier
in your ApplicationController (which is now done automatically by the gem),
@@ -206,12 +213,12 @@ all errors will be rescued by the #rescue_action_in_public provided by the gem.
If you want to log arbitrary things which you've rescued yourself from a
controller, you can do something like this:
- ...
- rescue => ex
- notify_hoptoad(ex)
- flash[:failure] = 'Encryptions could not be rerouted, try again.'
- end
- ...
+ ...
+ rescue => ex
+ notify_hoptoad(ex)
+ flash[:failure] = 'Encryptions could not be rerouted, try again.'
+ end
+ ...
The #notify_hoptoad call will send the notice over to Hoptoad for later
analysis. While in your controllers you use the notify_hoptoad method, anywhere
@@ -221,7 +228,8 @@ To perform custom error processing after Hoptoad has been notified, define the
instance method #rescue_action_in_public_without_hoptoad(exception) in your
controller.
-== Tracking deployments in Hoptoad
+Tracking deployments in Hoptoad
+-------------------------------
Paying Hoptoad plans support the ability to track deployments of your application in Hoptoad.
By notifying Hoptoad of your application deployments, all errors are resolved when a deploy occurs,
@@ -231,28 +239,34 @@ Additionally, it's possible to review the errors in Hoptoad that occurred before
When Hoptoad is installed as a gem, you need to add
- require 'hoptoad_notifier/capistrano'
+ require 'hoptoad_notifier/capistrano'
to your deploy.rb
-== Going beyond exceptions
+If you don't use Capistrano, then you can use the following rake task from your
+deployment process to notify Hoptoad:
+
+ rake hoptoad:deploy TO=#{rails_env} REVISION=#{current_revision} REPO=#{repository} USER=#{local_user}
+
+Going beyond exceptions
+-----------------------
You can also pass a hash to notify_hoptoad method and store whatever you want,
not just an exception. And you can also use it anywhere, not just in
controllers:
- begin
- params = {
- # params that you pass to a method that can throw an exception
- }
- my_unpredicable_method(params)
- rescue => e
- HoptoadNotifier.notify(
- :error_class => "Special Error",
- :error_message => "Special Error: #{e.message}",
- :parameters => params
- )
- end
+ begin
+ params = {
+ # params that you pass to a method that can throw an exception
+ }
+ my_unpredicable_method(params)
+ rescue => e
+ HoptoadNotifier.notify(
+ :error_class => "Special Error",
+ :error_message => "Special Error: #{e.message}",
+ :parameters => params
+ )
+ end
While in your controllers you use the notify_hoptoad method, anywhere else in
your code, use HoptoadNotifier.notify. Hoptoad will get all the information
@@ -264,17 +278,17 @@ about the error itself. As for a hash, these are the keys you should pass:
Hoptoad merges the hash you pass with these default options:
- {
- :api_key => HoptoadNotifier.api_key,
- :error_message => 'Notification',
- :backtrace => caller,
- :parameters => {},
- :session => {}
- }
+ {
+ :api_key => HoptoadNotifier.api_key,
+ :error_message => 'Notification',
+ :backtrace => caller,
+ :parameters => {},
+ :session => {}
+ }
You can override any of those parameters.
-=== Sending shell environment variables when "Going beyond exceptions"
+### Sending shell environment variables when "Going beyond exceptions"
One common request we see is to send shell environment variables along with
manual exception notification. We recommend sending them along with CGI data
@@ -283,7 +297,8 @@ or Rack environment (:cgi_data or :rack_env keys, respectively.)
See HoptoadNotifier::Notice#initialize in lib/hoptoad_notifier/notice.rb for
more details.
-== Filtering
+Filtering
+---------
You can specify a whitelist of errors, that Hoptoad will not report on. Use
this feature when you are so apathetic to certain errors that you don't want
@@ -294,80 +309,84 @@ notifications (when #notify is called directly).
Hoptoad ignores the following exceptions by default:
- ActiveRecord::RecordNotFound
- ActionController::RoutingError
- ActionController::InvalidAuthenticityToken
- ActionController::UnknownAction
- CGI::Session::CookieStore::TamperedWithCookie
+ AbstractController::ActionNotFound
+ ActiveRecord::RecordNotFound
+ ActionController::RoutingError
+ ActionController::InvalidAuthenticityToken
+ ActionController::UnknownAction
+ CGI::Session::CookieStore::TamperedWithCookie
To ignore errors in addition to those, specify their names in your Hoptoad
configuration block.
- HoptoadNotifier.configure do |config|
- config.api_key = '1234567890abcdef'
- config.ignore << ActiveRecord::IgnoreThisError
- end
+ HoptoadNotifier.configure do |config|
+ config.api_key = '1234567890abcdef'
+ config.ignore << "ActiveRecord::IgnoreThisError"
+ end
To ignore *only* certain errors (and override the defaults), use the
#ignore_only attribute.
- HoptoadNotifier.configure do |config|
- config.api_key = '1234567890abcdef'
- config.ignore_only = [ActiveRecord::IgnoreThisError]
- end
+ HoptoadNotifier.configure do |config|
+ config.api_key = '1234567890abcdef'
+ config.ignore_only = ["ActiveRecord::IgnoreThisError"]
+ end
To ignore certain user agents, add in the #ignore_user_agent attribute as a
string or regexp:
- HoptoadNotifier.configure do |config|
- config.api_key = '1234567890abcdef'
- config.ignore_user_agent << /Ignored/
- config.ignore_user_agent << 'IgnoredUserAgent'
- end
+ HoptoadNotifier.configure do |config|
+ config.api_key = '1234567890abcdef'
+ config.ignore_user_agent << /Ignored/
+ config.ignore_user_agent << 'IgnoredUserAgent'
+ end
To ignore exceptions based on other conditions, use #ignore_by_filter:
- HoptoadNotifier.configure do |config|
- config.api_key = '1234567890abcdef'
- config.ignore_by_filter do |exception_data|
- true if exception_data[:error_class] == "RuntimeError"
+ HoptoadNotifier.configure do |config|
+ config.api_key = '1234567890abcdef'
+ config.ignore_by_filter do |exception_data|
+ true if exception_data[:error_class] == "RuntimeError"
+ end
end
- end
To replace sensitive information sent to the Hoptoad service with [FILTERED] use #params_filters:
- HoptoadNotifier.configure do |config|
- config.api_key = '1234567890abcdef'
- config.params_filters << "credit_card_number"
- end
+ HoptoadNotifier.configure do |config|
+ config.api_key = '1234567890abcdef'
+ config.params_filters << "credit_card_number"
+ end
Note that, when rescuing exceptions within an ActionController method,
hoptoad_notifier will reuse filters specified by #filter_parameter_logging.
-== Testing
+Testing
+-------
When you run your tests, you might notice that the Hoptoad service is recording
notices generated using #notify when you don't expect it to. You can
use code like this in your test_helper.rb to redefine that method so those
errors are not reported while running tests.
- module HoptoadNotifier
- def self.notify(thing)
- # do nothing.
+ module HoptoadNotifier
+ def self.notify(thing)
+ # do nothing.
+ end
end
- end
-== Proxy Support
+Proxy Support
+-------------
The notifier supports using a proxy, if your server is not able to directly reach the Hoptoad servers. To configure the proxy settings, added the following information to your Hoptoad configuration block.
- HoptoadNotifier.configure do |config|
- config.proxy_host = ...
- config.proxy_port = ...
- config.proxy_user = ...
- config.proxy_pass = ...
+ HoptoadNotifier.configure do |config|
+ config.proxy_host = ...
+ config.proxy_port = ...
+ config.proxy_user = ...
+ config.proxy_pass = ...
-== Supported Rails versions
+Supported Rails versions
+------------------------
See SUPPORTED_RAILS_VERSIONS for a list of official supported versions of
Rails.
@@ -376,19 +395,41 @@ Please open up a support ticket on Tender ( http://help.hoptoadapp.com ) if
you're using a version of Rails that is not listed above and the notifier is
not working properly.
-== Javascript Notifer
+Javascript Notifer
+------------------
+
+To automatically include the Javascript node on every page, use this helper method from your layouts:
+
+ <%= hoptoad_javascript_notifier %>
+
+It's important to insert this very high in the markup, above all other javascript. Example:
+
+ <!DOCTYPE html>
+ <html>
+ <head>
+ <meta charset="utf8">
+ <%= hoptoad_javascript_notifier %>
+ <!-- more javascript -->
+ </head>
+ <body>
+ ...
+ </body>
+ </html>
+
+This helper will automatically use the API key, host, and port specified in the configuration.
+
+Credits
+-------
+
+![thoughtbot](http://thoughtbot.com/images/tm/logo.png)
-To automatically include the Javascript node on every page, set the
-:js_notifier to true:
+HoptoadNotifier is maintained and funded by [thoughtbot, inc](http://thoughtbot.com/community)
- HoptoadNotifier.configure do |config|
- config.js_notifier = true
- end
+Thank you to all [the contributors](https://github.com/thoughtbot/hoptoad_notifier/contributors)!
-It automatically uses the API key, host, and port specified in the
-configuration.
+The names and logos for thoughtbot are trademarks of thoughtbot, inc.
-== Thanks
+License
+-------
-Thanks to Eugene Bolshakov for the excellent write-up on GOING BEYOND
-EXCEPTIONS, which we have included above.
+HoptoadNotifier is Copyright © 2008-2011 thoughtbot. It is free software, and may be redistributed under the terms specified in the MIT-LICENSE file.
View
93 README_FOR_HEROKU_ADDON.md
@@ -0,0 +1,93 @@
+Hoptoad
+===========
+Send your application errors to our hosted service and reclaim your inbox.
+
+1. Installing the Heroku add-on
+----------------------------
+To use Hoptoad on Heroku, install the Hoptoad add-on:
+
+ $ heroku addons:add hoptoad:basic # This adds the the basic plan.
+ # If you'd like another plan, specify that instead.
+
+2. Including the Hoptoad notifier in your application
+--------------------------------------------------
+After adding the Hoptoad add-on, you will need to install and configure the Hoptoad notifier.
+
+Your application connects to Hoptoad with an API key. On Heroku, this is automatically provided to your
+application in `ENV['HOPTOAD_API_KEY']`, so installation should be a snap!
+
+### Rails 3.x
+
+Add the hoptoad_notifier and heroku gems to your Gemfile. In Gemfile:
+
+ gem 'hoptoad_notifier'
+ gem 'heroku'
+
+Then from your project's RAILS_ROOT, run:
+
+ $ bundle install
+ $ script/rails generate hoptoad --heroku
+
+### Rails 2.x
+
+Install the heroku gem if you haven't already:
+
+ gem install heroku
+
+Add the hoptoad_notifier gem to your app. In config/environment.rb:
+
+ config.gem 'hoptoad_notifier'
+
+Then from your project's RAILS_ROOT, run:
+
+ $ rake gems:install
+ $ rake gems:unpack GEM=hoptoad_notifier
+ $ script/generate hoptoad --heroku
+
+As always, if you choose not to vendor the hoptoad_notifier gem, make sure
+every server you deploy to has the gem installed or your application won't start.
+
+### Rack applications
+
+In order to use hoptoad_notifier in a non-Rails rack app, just load the hoptoad_notifier, configure your API key, and use the HoptoadNotifier::Rack middleware:
+
+ require 'rubygems'
+ require 'rack'
+ require 'hoptoad_notifier'
+
+ HoptoadNotifier.configure do |config|
+ config.api_key = `ENV['HOPTOAD_API_KEY']`
+ end
+
+ app = Rack::Builder.app do
+ use HoptoadNotifier::Rack
+ run lambda { |env| raise "Rack down" }
+ end
+
+### Rails 1.x
+
+For Rails 1.x, visit the [Hoptoad notifier's README on GitHub](http://github.com/thoughtbot/hoptoad_notifier),
+and be sure to use `ENV['HOPTOAD_API_KEY']` where your API key is required in configuration code.
+
+3. Configure your notification settings (important!)
+---------------------------------------------------
+
+Once you have included and configured the notifier in your application,
+you will want to configure your notification settings.
+
+This is important - without setting your email address, you won't receive notification emails.
+
+Hoptoad can deliver exception notifications to your email inbox. To configure these delivery settings:
+
+1. Visit your application's Hoptoad Add-on page, like [ http://api.heroku.com/myapps/my-great-app/addons/hoptoad:basic ](http://api.heroku.com/myapps/my-great-app/addons/hoptoad:basic)
+2. Click "Go to Hoptoad admin" to configure the Hoptoad Add-on on the Hoptoadapp.com website
+3. Click the "Profile" button in the header to edit your email address and notification settings.
+
+4. Optionally: Set up deploy notification
+-----------------------------------------
+
+If your Hoptoad plan supports deploy notification, set it up for your Heroku application like this:
+
+ rake hoptoad:heroku:add_deploy_notification
+
+This will install a Heroku [HTTP Deploy Hook](http://docs.heroku.com/deploy-hooks) to notify Hoptoad of the deploy.
View
32 Rakefile
@@ -5,7 +5,7 @@ require 'rake/gempackagetask'
require 'cucumber/rake/task'
desc 'Default: run unit tests.'
-task :default => [:test, :cucumber]
+task :default => [:test, "cucumber:rails:all"]
desc 'Test the hoptoad_notifier gem.'
Rake::TestTask.new(:test) do |t|
@@ -66,7 +66,7 @@ EOF
File.open(file, "w") do |f|
f.write <<EOF
-Version #{version} - #{Date.today}
+Version #{version} - #{Time.now}
===============================================================================
#{`git log $(git tag | tail -1)..HEAD | git shortlog`}
@@ -123,14 +123,11 @@ gemspec = Gem::Specification.new do |s|
s.require_path = 'lib'
s.test_files = Dir[*['test/**/*_test.rb']]
- s.has_rdoc = true
- s.extra_rdoc_files = ["README.rdoc"]
- s.rdoc_options = ['--line-numbers', "--main", "README.rdoc"]
-
+ s.add_runtime_dependency("builder")
s.add_runtime_dependency("activesupport")
s.add_development_dependency("activerecord")
s.add_development_dependency("actionpack")
- s.add_development_dependency("jferris-mocha")
+ s.add_development_dependency("bourne")
s.add_development_dependency("nokogiri")
s.add_development_dependency("shoulda")
@@ -191,19 +188,32 @@ end
task :cucumber => [:gemspec, :vendor_test_gems]
+def run_rails_cucumbr_task(version, additional_cucumber_args)
+ puts "Testing Rails #{version}"
+ if version.empty?
+ raise "No Rails version specified - make sure ENV['RAILS_VERSION'] is set, e.g. with `rake cucumber:rails:all`"
+ end
+ ENV['RAILS_VERSION'] = version
+ system("cucumber --format #{ENV['CUCUMBER_FORMAT'] || 'progress'} #{additional_cucumber_args} features/rails.feature features/rails_with_js_notifier.feature")
+end
+
def define_rails_cucumber_tasks(additional_cucumber_args = '')
namespace :rails do
RAILS_VERSIONS.each do |version|
desc "Test integration of the gem with Rails #{version}"
task version => [:gemspec, :vendor_test_gems] do
- puts "Testing Rails #{version}"
- ENV['RAILS_VERSION'] = version
- system("cucumber --format #{ENV['CUCUMBER_FORMAT'] || 'progress'} #{additional_cucumber_args} features/rails.feature")
+ exit 1 unless run_rails_cucumbr_task(version, additional_cucumber_args)
end
end
desc "Test integration of the gem with all Rails versions"
- task :all => RAILS_VERSIONS
+ task :all do
+ results = RAILS_VERSIONS.map do |version|
+ run_rails_cucumbr_task(version, additional_cucumber_args)
+ end
+
+ exit 1 unless results.all?
+ end
end
end
View
12 SUPPORTED_RAILS_VERSIONS
@@ -1,10 +1,10 @@
-1.2.6
-2.0.2
-2.1.0
-2.1.2
-2.2.2
2.3.2
2.3.4
2.3.5
2.3.8
-3.0.0.rc
+2.3.9
+2.3.10
+3.0.0
+3.0.1
+3.0.2
+3.0.3
View
4 features/metal.feature
@@ -14,10 +14,10 @@ Feature: Rescue errors in Rails middleware
raise "Explode"
end
"""
- When I perform a request to "http://example.com:123/test/index?param=value"
+ When I perform a request to "http://example.com:123/metal/index?param=value"
Then I should receive the following Hoptoad notification:
| error message | RuntimeError: Explode |
| error class | RuntimeError |
| parameters | param: value |
- | url | http://example.com:123/test/index?param=value |
+ | url | http://example.com:123/metal/index?param=value |
View
85 features/rails.feature
@@ -33,6 +33,27 @@ Feature: Install the Gem in a Rails application
And I run the hoptoad generator with ""
Then I should receive a Hoptoad notification
+ Scenario: Configuration within initializer isn't overridden by Railtie
+ When I generate a new Rails application
+ And I configure the Hoptoad shim
+ And I configure my application to require the "hoptoad_notifier" gem
+ And I run the hoptoad generator with "-k myapikey"
+ Then the command should have run successfully
+ When I configure the notifier to use the following configuration lines:
+ """
+ config.api_key = "myapikey"
+ config.project_root = "argle/bargle"
+ """
+ And I define a response for "TestController#index":
+ """
+ session[:value] = "test"
+ raise RuntimeError, "some message"
+ """
+ And I route "/test/index" to "test#index"
+ And I perform a request to "http://example.com:123/test/index?param=value"
+ Then I should receive the following Hoptoad notification:
+ | project-root | argle/bargle |
+
Scenario: Try to install without an api key
When I generate a new Rails application
And I configure my application to require the "hoptoad_notifier" gem
@@ -90,46 +111,6 @@ Feature: Install the Gem in a Rails application
| parameters | param: value |
| url | http://example.com:123/test/index?param=value |
- Scenario: Include the Javascript notifier automatically
- When I generate a new Rails application
- And I configure the Hoptoad shim
- And I configure my application to require the "hoptoad_notifier" gem
- When I configure the notifier to use the following configuration lines:
- """
- config.api_key = "myapikey"
- config.js_notifier = true
- """
- And I define a response for "TestController#index":
- """
- render :text => "<html><head></head><body></body></html>"
- """
- And I route "/test/index" to "test#index"
- And I perform a request to "http://example.com:123/test/index"
- Then I should see the notifier JavaScript for the following:
- | api_key | environment | host |
- | myapikey | production | hoptoadapp.com |
-
- Scenario: Include the Javascript notifier automatically using custom notifier configuration settings
- When I generate a new Rails application
- And I configure the Hoptoad shim
- And I configure my application to require the "hoptoad_notifier" gem
- When I configure the notifier to use the following configuration lines:
- """
- config.api_key = "myapikey!"
- config.host = "myhoptoad.com"
- config.port = 3001
- config.js_notifier = true
- """
- And I define a response for "TestController#index":
- """
- render :text => "<html><head></head><body></body></html>"
- """
- And I route "/test/index" to "test#index"
- And I perform a request to "http://example.com:123/test/index"
- Then I should see the notifier JavaScript for the following:
- | api_key | environment | host |
- | myapikey! | production | myhoptoad.com:3001 |
-
Scenario: The gem should not be considered a framework gem
When I generate a new Rails application
And I configure the Hoptoad shim
@@ -151,8 +132,8 @@ Feature: Install the Gem in a Rails application
When I generate a new Rails application
And I configure the Hoptoad shim
And I configure the Heroku rake shim
+ And I configure the Heroku gem shim with "myapikey"
And I configure my application to require the "hoptoad_notifier" gem
- And I set the environment variable "HOPTOAD_API_KEY" to "myapikey"
And I run the hoptoad generator with "--heroku"
Then the command should have run successfully
And I should receive a Hoptoad notification
@@ -234,3 +215,25 @@ Feature: Install the Gem in a Rails application
| params | secret: [FILTERED] |
| session | secret: [FILTERED] |
| url | http://example.com:123/test/index?param=value |
+
+ Scenario: Notify hoptoad within the controller
+ When I generate a new Rails application
+ And I configure the Hoptoad shim
+ And I configure my application to require the "hoptoad_notifier" gem
+ And I run the hoptoad generator with "-k myapikey"
+ And I define a response for "TestController#index":
+ """
+ session[:value] = "test"
+ notify_hoptoad(RuntimeError.new("some message"))
+ render :nothing => true
+ """
+ And I route "/test/index" to "test#index"
+ And I perform a request to "http://example.com:123/test/index?param=value"
+ Then I should receive the following Hoptoad notification:
+ | component | test |
+ | action | index |
+ | error message | RuntimeError: some message |
+ | error class | RuntimeError |
+ | session | value: test |
+ | parameters | param: value |
+ | url | http://example.com:123/test/index?param=value |
View
78 features/rails_with_js_notifier.feature
@@ -0,0 +1,78 @@
+Feature: Install the Gem in a Rails application and enable the JavaScript notifier
+
+ Background:
+ Given I have built and installed the "hoptoad_notifier" gem
+
+ Scenario: Include the Javascript notifier when enabled
+ When I generate a new Rails application
+ And I configure the Hoptoad shim
+ And I configure my application to require the "hoptoad_notifier" gem
+ When I configure the notifier to use the following configuration lines:
+ """
+ config.api_key = "myapikey"
+ """
+ And I define a response for "TestController#index":
+ """
+ render :inline => '<html><head profile="http://example.com"><%= hoptoad_javascript_notifier %></head><body></body></html>'
+ """
+ And I route "/test/index" to "test#index"
+ And I perform a request to "http://example.com:123/test/index"
+ Then I should see the notifier JavaScript for the following:
+ | api_key | environment | host |
+ | myapikey | production | hoptoadapp.com |
+ And the notifier JavaScript should provide the following errorDefaults:
+ | url | component | action |
+ | http://example.com:123/test/index | test | index |
+
+ Scenario: Include the Javascript notifier when enabled using custom configuration settings
+ When I generate a new Rails application
+ And I configure the Hoptoad shim
+ And I configure my application to require the "hoptoad_notifier" gem
+ When I configure the notifier to use the following configuration lines:
+ """
+ config.api_key = "myapikey!"
+ config.host = "myhoptoad.com"
+ config.port = 3001
+ """
+ And I define a response for "TestController#index":
+ """
+ render :inline => '<html><head><%= hoptoad_javascript_notifier %></head><body></body></html>'
+ """
+ And I route "/test/index" to "test#index"
+ And I perform a request to "http://example.com:123/test/index"
+ Then I should see the notifier JavaScript for the following:
+ | api_key | environment | host |
+ | myapikey! | production | myhoptoad.com:3001 |
+
+ Scenario: Don't include the Javascript notifier by default
+ When I generate a new Rails application
+ And I configure the Hoptoad shim
+ And I configure my application to require the "hoptoad_notifier" gem
+ When I configure the notifier to use the following configuration lines:
+ """
+ config.api_key = "myapikey!"
+ """
+ And I define a response for "TestController#index":
+ """
+ render :inline => "<html><head></head><body></body></html>"
+ """
+ And I route "/test/index" to "test#index"
+ And I perform a request to "http://example.com:123/test/index"
+ Then I should not see notifier JavaScript
+
+ Scenario: Don't include the Javascript notifier when enabled in non-public environments
+ When I generate a new Rails application
+ And I configure the Hoptoad shim
+ And I configure my application to require the "hoptoad_notifier" gem
+ When I configure the notifier to use the following configuration lines:
+ """
+ config.api_key = "myapikey!"
+ config.environment_name = 'test'
+ """
+ And I define a response for "TestController#index":
+ """
+ render :inline => '<html><head><%= hoptoad_javascript_notifier %></head><body></body></html>'
+ """
+ And I route "/test/index" to "test#index"
+ And I perform a request to "http://example.com:123/test/index" in the "test" environment
+ Then I should not see notifier JavaScript
View
2  features/sinatra.feature
@@ -13,7 +13,7 @@ Feature: Use the notifier in a Sinatra app
config.api_key = 'my_api_key'
end
- class FontaneApp < Sinatra::Default
+ class FontaneApp < Sinatra::Base
use HoptoadNotifier::Rack
enable :raise_errors
View
13 features/step_definitions/metal_steps.rb
@@ -6,5 +6,18 @@
file.puts definition
file.puts "end"
end
+ When %{the metal endpoint "#{class_name}" is mounted in the Rails 3 routes.rb} if rails3?
end
+When /^the metal endpoint "([^\"]*)" is mounted in the Rails 3 routes.rb$/ do |class_name|
+ routesrb = File.join(RAILS_ROOT, "config", "routes.rb")
+ routes = IO.readlines(routesrb)
+ rack_route = "match '/metal(/*other)' => #{class_name}"
+ routes = routes[0..-2] + [rack_route, routes[-1]]
+ File.open(routesrb, "w") do |f|
+ f.puts "require 'app/metal/#{class_name.underscore}'"
+ routes.each do |route_line|
+ f.puts route_line
+ end
+ end
+end
View
122 features/step_definitions/rails_application_steps.rb
@@ -34,6 +34,10 @@
end
end
+When /^I print the console output$/ do
+ puts @terminal.output
+end
+
Given /^I have installed the "([^\"]*)" gem$/ do |gem_name|
@terminal.install_gem(gem_name)
end
@@ -195,72 +199,16 @@ def rails_non_initializer_hoptoad_config_file
end
When /^I perform a request to "([^\"]*)"$/ do |uri|
- if rails3?
- request_script = <<-SCRIPT
- require 'config/environment'
-
- env = Rack::MockRequest.env_for(#{uri.inspect})
- response = RailsRoot::Application.call(env).last
-
- if response.is_a?(Array)
- puts response.join
- else
- puts response.body
- end
- SCRIPT
- File.open(File.join(RAILS_ROOT, 'request.rb'), 'w') { |file| file.write(request_script) }
- @terminal.cd(RAILS_ROOT)
- @terminal.run("./script/rails runner -e production request.rb")
- elsif rails_uses_rack?
- request_script = <<-SCRIPT
- require 'config/environment'
-
- env = Rack::MockRequest.env_for(#{uri.inspect})
- app = Rack::Lint.new(ActionController::Dispatcher.new)
-
- status, headers, body = app.call(env)
-
- response = ""
- if body.respond_to?(:to_str)
- response << body
- else
- body.each { |part| response << part }
- end
-
- puts response
- SCRIPT
- File.open(File.join(RAILS_ROOT, 'request.rb'), 'w') { |file| file.write(request_script) }
- @terminal.cd(RAILS_ROOT)
- @terminal.run("./script/runner -e production request.rb")
- else
- uri = URI.parse(uri)
- request_script = <<-SCRIPT
- require 'cgi'
- class CGIWrapper < CGI
- def initialize(*args)
- @env_table = {}
- @stdinput = $stdin
- super(*args)
- end
- attr_reader :env_table
- end
- $stdin = StringIO.new("")
- cgi = CGIWrapper.new
- cgi.env_table.update({
- 'HTTPS' => 'off',
- 'REQUEST_METHOD' => "GET",
- 'HTTP_HOST' => #{[uri.host, uri.port].join(':').inspect},
- 'SERVER_PORT' => #{uri.port.inspect},
- 'REQUEST_URI' => #{uri.request_uri.inspect},
- 'PATH_INFO' => #{uri.path.inspect},
- 'QUERY_STRING' => #{uri.query.inspect}
- })
- require 'dispatcher' unless defined?(ActionController::Dispatcher)
- Dispatcher.dispatch(cgi)
- SCRIPT
- File.open(File.join(RAILS_ROOT, 'request.rb'), 'w') { |file| file.write(request_script) }
- @terminal.cd(RAILS_ROOT)
- @terminal.run("./script/runner -e production request.rb")
+ perform_request(uri)
+end
+
+When /^I perform a request to "([^\"]*)" in the "([^\"]*)" environment$/ do |uri, environment|
+ perform_request(uri, environment)
+end
+
+Given /^the response page for a "([^\"]*)" error is$/ do |error, html|
+ File.open(File.join(RAILS_ROOT, "public", "#{error}.html"), "w") do |file|
+ file.write(html)
end
end
@@ -279,6 +227,7 @@ def initialize(*args)
doc.should have_content('//component', hash['component']) if hash['component']
doc.should have_content('//action', hash['action']) if hash['action']
+ doc.should have_content('//server-environment/project-root', hash['project-root']) if hash['project-root']
if hash['session']
session_key, session_value = hash['session'].split(': ')
@@ -350,6 +299,20 @@ def initialize(*args)
@terminal.invoke_heroku_rake_tasks_locally = true
end
+When /^I configure the Heroku gem shim with "([^\"]*)"$/ do |api_key|
+ heroku_script_bin = File.join(TEMP_DIR, "bin")
+ FileUtils.mkdir_p(heroku_script_bin)
+ heroku_script = File.join(heroku_script_bin, "heroku")
+ File.open(heroku_script, "w") do |f|
+ f.puts "#!/bin/bash"
+ f.puts "if [[ $1 == 'console' && $2 == 'puts ENV[%{HOPTOAD_API_KEY}]' ]]; then"
+ f.puts " echo #{api_key}"
+ f.puts "fi"
+ end
+ FileUtils.chmod(0755, heroku_script)
+ @terminal.prepend_path(heroku_script_bin)
+end
+
When /^I configure the application to filter parameter "([^\"]*)"$/ do |parameter|
if rails3?
application_filename = File.join(RAILS_ROOT, 'config', 'application.rb')
@@ -383,11 +346,14 @@ def initialize(*args)
Then /^I should see the notifier JavaScript for the following:$/ do |table|
hash = table.hashes.first
host = hash['host'] || 'hoptoadapp.com'
+ secure = hash['secure'] || false
api_key = hash['api_key']
environment = hash['environment'] || 'production'
- response = Nokogiri::HTML.parse('<html>' + @terminal.output.split('<html>').last)
- response.css("script[type='text/javascript'][src='http://#{host}/javascripts/notifier.js']").first.should_not be_nil
+ document_body = '<html>' + @terminal.output.split('<html>').last
+ document_body.should include("#{host}/javascripts/notifier.js")
+
+ response = Nokogiri::HTML.parse(document_body)
response.css("script[type='text/javascript']:last-child").each do |element|
content = element.content
content.should include("Hoptoad.setKey('#{api_key}');")
@@ -395,3 +361,23 @@ def initialize(*args)
content.should include("Hoptoad.setEnvironment('#{environment}');")
end
end
+
+Then "the notifier JavaScript should provide the following errorDefaults:" do |table|
+ hash = table.hashes.first
+
+ document_body = '<html>' + @terminal.output.split('<html>').last
+
+ response = Nokogiri::HTML.parse(document_body)
+ response.css("script[type='text/javascript']:last-child").each do |element|
+ content = element.content
+
+ hash.each do |key, value|
+ content.should =~ %r{Hoptoad\.setErrorDefaults.*#{key}: "#{value}}m
+ end
+ end
+end
+
+Then /^I should not see notifier JavaScript$/ do
+ response = Nokogiri::HTML.parse('<html>' + @terminal.output.split('<html>').last)
+ response.at_css("script[type='text/javascript'][src$='/javascripts/notifier.js']").should be_nil
+end
View
10 features/support/hoptoad_shim.rb.template
@@ -3,5 +3,13 @@ require 'sham_rack'
ShamRack.at("hoptoadapp.com") do |env|
xml = env['rack.input'].read
puts "Recieved the following exception:\n#{xml}"
- ["200 OK", { "Content-type" => "text/xml" }, "<notice/>"]
+ response = <<-end_xml
+<?xml version="1.0" encoding="UTF-8"?>
+<notice>
+ <error-id type="integer">3799307</error-id>
+ <url>http://sample.hoptoadapp.com/errors/3799307/notices/643732254</url>
+ <id type="integer">643732254</id>
+</notice>
+ end_xml
+ ["200 OK", { "Content-type" => "text/xml" }, response]
end
View
4 features/support/matchers.rb
@@ -1,4 +1,4 @@
-RSpec::Matchers.define :have_content do |xpath, content|
+Spec::Matchers.define :have_content do |xpath, content|
match do |document|
@elements = document.search(xpath)
@@ -31,3 +31,5 @@
end
end
end
+
+World(Spec::Matchers)
View
70 features/support/rails.rb
@@ -72,6 +72,76 @@ def config_gem(gem_name)
raise "Couldn't find #{run.inspect} in #{environment_path}"
end
end
+
+ def perform_request(uri, environment = 'production')
+ if rails3?
+ request_script = <<-SCRIPT
+ require 'config/environment'
+
+ env = Rack::MockRequest.env_for(#{uri.inspect})
+ response = RailsRoot::Application.call(env).last
+
+ if response.is_a?(Array)
+ puts response.join
+ else
+ puts response.body
+ end
+ SCRIPT
+ File.open(File.join(RAILS_ROOT, 'request.rb'), 'w') { |file| file.write(request_script) }
+ @terminal.cd(RAILS_ROOT)
+ @terminal.run("./script/rails runner -e #{environment} request.rb")
+ elsif rails_uses_rack?
+ request_script = <<-SCRIPT
+ require 'config/environment'
+
+ env = Rack::MockRequest.env_for(#{uri.inspect})
+ app = Rack::Lint.new(ActionController::Dispatcher.new)
+
+ status, headers, body = app.call(env)
+
+ response = ""
+ if body.respond_to?(:to_str)
+ response << body
+ else
+ body.each { |part| response << part }
+ end
+
+ puts response
+ SCRIPT
+ File.open(File.join(RAILS_ROOT, 'request.rb'), 'w') { |file| file.write(request_script) }
+ @terminal.cd(RAILS_ROOT)
+ @terminal.run("./script/runner -e #{environment} request.rb")
+ else
+ uri = URI.parse(uri)
+ request_script = <<-SCRIPT
+ require 'cgi'
+ class CGIWrapper < CGI
+ def initialize(*args)
+ @env_table = {}
+ @stdinput = $stdin
+ super(*args)
+ end
+ attr_reader :env_table
+ end
+ $stdin = StringIO.new("")
+ cgi = CGIWrapper.new
+ cgi.env_table.update({
+ 'HTTPS' => 'off',
+ 'REQUEST_METHOD' => "GET",
+ 'HTTP_HOST' => #{[uri.host, uri.port].join(':').inspect},
+ 'SERVER_PORT' => #{uri.port.inspect},
+ 'REQUEST_URI' => #{uri.request_uri.inspect},
+ 'PATH_INFO' => #{uri.path.inspect},
+ 'QUERY_STRING' => #{uri.query.inspect}
+ })
+ require 'dispatcher' unless defined?(ActionController::Dispatcher)
+ Dispatcher.dispatch(cgi)
+ SCRIPT
+ File.open(File.join(RAILS_ROOT, 'request.rb'), 'w') { |file| file.write(request_script) }
+ @terminal.cd(RAILS_ROOT)
+ @terminal.run("./script/runner -e #{environment} request.rb")
+ end
+ end
end
World(RailsHelpers)
View
14 features/support/terminal.rb
@@ -4,6 +4,12 @@
@terminal = Terminal.new
end
+After do |story|
+ if story.failed?
+ # puts @terminal.output
+ end
+end
+
class Terminal
attr_reader :output, :status
attr_accessor :environment_variables, :invoke_heroku_rake_tasks_locally
@@ -32,7 +38,8 @@ def run(command)
output << "#{command}\n"
FileUtils.cd(@cwd) do
- cmdline = "#{environment_settings} #{command} 2>&1"
+ # The ; forces ruby to shell out so the env settings work right
+ cmdline = "#{environment_settings} #{command} 2>&1 ; "
logger.debug(cmdline)
result = `#{cmdline}`
logger.debug(result)
@@ -56,6 +63,7 @@ def echo(string)
def build_and_install_gem(gemspec)
pkg_dir = File.join(TEMP_DIR, 'pkg')
FileUtils.mkdir_p(pkg_dir)
+ `rake gemspec`
output = `gem build #{gemspec} 2>&1`
gem_file = Dir.glob("*.gem").first
unless gem_file
@@ -74,6 +82,10 @@ def uninstall_gem(gem)
`gem uninstall -i #{BUILT_GEM_ROOT} #{gem}`
end
+ def prepend_path(path)
+ @environment_variables['PATH'] = path + ":" + @environment_variables['PATH']
+ end
+
private
def install_gem_to(root, gem)
View
42 features/user_informer.feature
@@ -0,0 +1,42 @@
+Feature: Inform the user of the hoptoad notice that was just created
+
+ Background:
+ Given I have built and installed the "hoptoad_notifier" gem
+
+ Scenario: Rescue an exception in a controller
+ When I generate a new Rails application
+ And I configure the Hoptoad shim
+ And I configure my application to require the "hoptoad_notifier" gem
+ And I run the hoptoad generator with "-k myapikey"
+ And I define a response for "TestController#index":
+ """
+ raise RuntimeError, "some message"
+ """
+ And the response page for a "500" error is
+ """
+ <!-- HOPTOAD ERROR -->
+ """
+ And I route "/test/index" to "test#index"
+ And I perform a request to "http://example.com:123/test/index?param=value"
+ Then I should see "Hoptoad Error 3799307"
+
+ Scenario: Rescue an exception in a controller with a custom error string
+ When I generate a new Rails application
+ And I configure the Hoptoad shim
+ And I configure my application to require the "hoptoad_notifier" gem
+ And I configure the notifier to use the following configuration lines:
+ """
+ config.user_information = 'Error #{{ error_id }}'
+ """
+ And I run the hoptoad generator with "-k myapikey"
+ And I define a response for "TestController#index":
+ """
+ raise RuntimeError, "some message"
+ """
+ And the response page for a "500" error is
+ """
+ <!-- HOPTOAD ERROR -->
+ """
+ And I route "/test/index" to "test#index"
+ And I perform a request to "http://example.com:123/test/index?param=value"
+ Then I should see "Error #3799307"
View
27 generators/hoptoad/hoptoad_generator.rb
@@ -32,7 +32,8 @@ def manifest
m.append_to 'config/environment.rb', "require 'config/hoptoad'"
end
end
- m.rake "hoptoad:test", :generate_only => true
+ determine_api_key if heroku?
+ m.rake "hoptoad:test --trace", :generate_only => true
end
end
@@ -44,6 +45,30 @@ def api_key_expression
end
end
+ def determine_api_key
+ puts "Attempting to determine your API Key from Heroku..."
+ ENV['HOPTOAD_API_KEY'] = heroku_api_key
+ if ENV['HOPTOAD_API_KEY'].blank?
+ puts "... Failed."
+ puts "WARNING: We were unable to detect the Hoptoad API Key from your Heroku environment."
+ puts "Your Heroku application environment may not be configured correctly."
+ exit 1
+ else
+ puts "... Done."
+ puts "Heroku's Hoptoad API Key is '#{ENV['HOPTOAD_API_KEY']}'"
+ end
+ end
+
+ def heroku_api_key
+ `heroku console 'puts ENV[%{HOPTOAD_API_KEY}]'`.split("\n").first
+ end
+
+ def heroku?
+ options[:heroku] ||
+ system("grep HOPTOAD_API_KEY config/initializers/hoptoad.rb") ||
+ system("grep HOPTOAD_API_KEY config/environment.rb")
+ end
+
def use_initializer?
Rails::VERSION::MAJOR > 1
end
View
9 lib/hoptoad_notifier.rb
@@ -1,13 +1,18 @@
require 'net/http'
require 'net/https'
require 'rubygems'
-require 'active_support'
+begin
+ require 'active_support'
+rescue LoadError
+ require 'activesupport'
+end
require 'hoptoad_notifier/version'
require 'hoptoad_notifier/configuration'
require 'hoptoad_notifier/notice'
require 'hoptoad_notifier/sender'
require 'hoptoad_notifier/backtrace'
require 'hoptoad_notifier/rack'
+require 'hoptoad_notifier/user_informer'
require 'hoptoad_notifier/railtie' if defined?(Rails::Railtie)
@@ -127,7 +132,7 @@ def send_notice(notice)
def build_notice_for(exception, opts = {})
exception = unwrap_exception(exception)
if exception.respond_to?(:to_hash)
- opts = opts.merge(exception)
+ opts = opts.merge(exception.to_hash)
else
opts = opts.merge(:exception => exception)
end
View
18 lib/hoptoad_notifier/configuration.rb
@@ -7,7 +7,8 @@ class Configuration
:http_open_timeout, :http_read_timeout, :ignore, :ignore_by_filters,
:ignore_user_agent, :notifier_name, :notifier_url, :notifier_version,
:params_filters, :project_root, :port, :protocol, :proxy_host,
- :proxy_pass, :proxy_port, :proxy_user, :secure, :framework, :js_notifier].freeze
+ :proxy_pass, :proxy_port, :proxy_user, :secure, :framework,
+ :user_information].freeze
# The API key for your project, found on the project edit form.
attr_accessor :api_key
@@ -62,9 +63,6 @@ class Configuration
# +true+ if you want to check for production errors matching development errors, +false+ otherwise.
attr_accessor :development_lookup
- # +true+ if you want to enable the JavaScript notifier in production environments
- attr_accessor :js_notifier
-
# The name of the environment the application is running in
attr_accessor :environment_name
@@ -83,6 +81,9 @@ class Configuration
# The logger used by HoptoadNotifier
attr_accessor :logger
+ # The text that the placeholder is replaced with. {{error_id}} is the actual error number.
+ attr_accessor :user_information
+
# The framework HoptoadNotifier is configured to use
attr_accessor :framework
@@ -111,7 +112,8 @@ class Configuration
'ActionController::RoutingError',
'ActionController::InvalidAuthenticityToken',
'CGI::Session::CookieStore::TamperedWithCookie',
- 'ActionController::UnknownAction']
+ 'ActionController::UnknownAction',
+ 'AbstractController::ActionNotFound']
alias_method :secure?, :secure
@@ -127,11 +129,11 @@ def initialize
@ignore_user_agent = []
@development_environments = %w(development test cucumber)
@development_lookup = true
- @js_notifier = false
@notifier_name = 'Hoptoad Notifier'
@notifier_version = VERSION
@notifier_url = 'http://hoptoadapp.com'
@framework = 'Standalone'
+ @user_information = 'Hoptoad Error {{error_id}}'
end
# Takes a block and adds it to the list of backtrace filters. When the filters
@@ -216,6 +218,10 @@ def protocol
end
end
+ def js_notifier=(*args)
+ warn '[HOPTOAD] config.js_notifier has been deprecated and has no effect. You should use <%= hoptoad_javascript_notifier %> directly at the top of your layouts. Be sure to place it before all other javascript.'
+ end
+
def environment_filters
warn 'config.environment_filters has been deprecated and has no effect.'
[]
View
10 lib/hoptoad_notifier/notice.rb
@@ -98,6 +98,7 @@ def initialize(args)
also_use_rack_params_filters
find_session_data
clean_params
+ clean_rack_request_data
end
# Converts the given notice to XML
@@ -254,6 +255,12 @@ def clean_params
end
end
+ def clean_rack_request_data
+ if cgi_data
+ cgi_data.delete("rack.request.form_vars")
+ end
+ end
+
def filter(hash)
if params_filters
hash.each do |key, value|
@@ -319,7 +326,8 @@ def rack_session
def also_use_rack_params_filters
if args[:rack_env]
- self.params_filters += rack_request.env["action_dispatch.parameter_filter"] || []
+ @params_filters ||= []
+ @params_filters += rack_request.env["action_dispatch.parameter_filter"] || []
end
end
View
6 lib/hoptoad_notifier/rack.rb
@@ -26,12 +26,14 @@ def call(env)
begin
response = @app.call(env)
rescue Exception => raised
- HoptoadNotifier.notify_or_ignore(raised, :rack_env => env)
+ error_id = HoptoadNotifier.notify_or_ignore(raised, :rack_env => env)
+ env['hoptoad.error_id'] = error_id
raise
end
if env['rack.exception']
- HoptoadNotifier.notify_or_ignore(env['rack.exception'], :rack_env => env)
+ error_id = HoptoadNotifier.notify_or_ignore(env['rack.exception'], :rack_env => env)
+ env['hoptoad.error_id'] = error_id
end
response
View
2  lib/hoptoad_notifier/rails.rb
@@ -23,6 +23,8 @@ def self.initialize
if defined?(::Rails.configuration) && ::Rails.configuration.respond_to?(:middleware)
::Rails.configuration.middleware.insert_after 'ActionController::Failsafe',
HoptoadNotifier::Rack
+ ::Rails.configuration.middleware.insert_after 'Rack::Lock',
+ HoptoadNotifier::UserInformer
end
HoptoadNotifier.configure(true) do |config|
View
3  lib/hoptoad_notifier/rails/action_controller_catcher.rb
@@ -14,7 +14,8 @@ def self.included(base) #:nodoc:
# any custom processing that is defined with Rails 2's exception helpers.
def rescue_action_in_public_with_hoptoad(exception)
unless hoptoad_ignore_user_agent?
- HoptoadNotifier.notify_or_ignore(exception, hoptoad_request_data)
+ error_id = HoptoadNotifier.notify_or_ignore(exception, hoptoad_request_data)
+ request.env['hoptoad.error_id'] = error_id
end
rescue_action_in_public_without_hoptoad(exception)
end
View
10 lib/hoptoad_notifier/rails/controller_methods.rb
@@ -6,10 +6,18 @@ module ControllerMethods
# This method should be used for sending manual notifications while you are still
# inside the controller. Otherwise it works like HoptoadNotifier.notify.
def notify_hoptoad(hash_or_exception)
- unless consider_all_requests_local || local_request?
+ unless hoptoad_local_request?
HoptoadNotifier.notify(hash_or_exception, hoptoad_request_data)
end
end
+
+ def hoptoad_local_request?
+ if defined?(::Rails.application.config)
+ ::Rails.application.config.consider_all_requests_local || request.local?
+ else
+ consider_all_requests_local || local_request?
+ end
+ end
def hoptoad_ignore_user_agent? #:nodoc:
# Rails 1.2.6 doesn't have request.user_agent, so check for it here
View
37 lib/hoptoad_notifier/rails/javascript_notifier.rb
@@ -2,40 +2,41 @@ module HoptoadNotifier
module Rails
module JavascriptNotifier
def self.included(base) #:nodoc:
- base.send(:after_filter, :insert_hoptoad_javascript_notifier)
+ base.send :helper_method, :hoptoad_javascript_notifier
end
private
- def insert_hoptoad_javascript_notifier
- return unless HoptoadNotifier.configuration.js_notifier
+ def hoptoad_javascript_notifier
+ return unless HoptoadNotifier.configuration.public?
- path = File.join(File.dirname(__FILE__), '..', '..', 'templates', 'javascript_notifier.erb')
+ path = File.join File.dirname(__FILE__), '..', '..', 'templates', 'javascript_notifier.erb'
host = HoptoadNotifier.configuration.host.dup
port = HoptoadNotifier.configuration.port
- host << ":#{port}" unless port == 80
+ host << ":#{port}" unless [80, 443].include?(port)
- options = {
- :file => path,
- :layout => false,
- :use_full_path => false,
- :locals => {
- :host => host,
- :api_key => HoptoadNotifier.configuration.api_key,
- :environment => HoptoadNotifier.configuration.environment_name
+ options = {
+ :file => path,
+ :layout => false,
+ :use_full_path => false,
+ :locals => {
+ :host => host,
+ :api_key => HoptoadNotifier.configuration.api_key,
+ :environment => HoptoadNotifier.configuration.environment_name,
+ :action_name => action_name,
+ :controller_name => controller_name,
+ :url => request.url
}
}
if @template
- javascript = @template.render(options)
+ @template.render(options)
else
- javascript = render_to_string(options)
+ render_to_string(options)
end
- if response.body.respond_to?(:gsub)
- response.body = response.body.gsub(/<(head)>/i, "<\\1>\n" + javascript)
- end
end
+
end
end
end
View
13 lib/hoptoad_notifier/rails3_tasks.rb
@@ -1,16 +1,7 @@
require 'hoptoad_notifier'
+require File.join(File.dirname(__FILE__), 'shared_tasks')
namespace :hoptoad do
- desc "Notify Hoptoad of a new deploy."
- task :deploy => :environment do
- require 'hoptoad_tasks'
- HoptoadTasks.deploy(:rails_env => ENV['TO'],
- :scm_revision => ENV['REVISION'],
- :scm_repository => ENV['REPO'],
- :local_username => ENV['USER'],
- :api_key => ENV['API_KEY'])
- end
-
desc "Verify your gem installation by sending a test exception to the hoptoad service"
task :test => [:environment] do
Rails.logger = Logger.new(STDOUT)
@@ -19,7 +10,7 @@
config.logger = Rails.logger
end
- require 'app/controllers/application_controller'
+ require './app/controllers/application_controller'
class HoptoadTestingException < RuntimeError; end
View
11 lib/hoptoad_notifier/railtie.rb
@@ -9,19 +9,22 @@ class Railtie < Rails::Railtie
initializer "hoptoad.use_rack_middleware" do |app|
app.config.middleware.use "HoptoadNotifier::Rack"
+ app.config.middleware.insert 0, "HoptoadNotifier::UserInformer"
end
config.after_initialize do
HoptoadNotifier.configure(true) do |config|
- config.logger = Rails.logger
- config.environment_name = Rails.env
- config.project_root = Rails.root
+ config.logger ||= Rails.logger
+ config.environment_name ||= Rails.env
+ config.project_root ||= Rails.root
config.framework = "Rails: #{::Rails::VERSION::STRING}"
end
if defined?(::ActionController::Base)
require 'hoptoad_notifier/rails/javascript_notifier'
-
+ require 'hoptoad_notifier/rails/controller_methods'
+
+ ::ActionController::Base.send(:include, HoptoadNotifier::Rails::ControllerMethods)
::ActionController::Base.send(:include, HoptoadNotifier::Rails::JavascriptNotifier)
end
end
View
15 lib/hoptoad_notifier/sender.rb
@@ -3,6 +3,14 @@ module HoptoadNotifier
class Sender
NOTICES_URI = '/notifier_api/v2/notices/'.freeze
+ HTTP_ERRORS = [Timeout::Error,
+ Errno::EINVAL,
+ Errno::ECONNRESET,
+ EOFError,
+ Net::HTTPBadResponse,
+ Net::HTTPHeaderSyntaxError,
+ Net::ProtocolError,
+ Errno::ECONNREFUSED].freeze
def initialize(options = {})
[:proxy_host, :proxy_port, :proxy_user, :proxy_pass, :protocol,
@@ -34,7 +42,7 @@ def send_to_hoptoad(data)
response = begin
http.post(url.path, data, HEADERS)
- rescue TimeoutError => e
+ rescue *HTTP_ERRORS => e
log :error, "Timeout while contacting the Hoptoad server."
nil
end
@@ -45,6 +53,11 @@ def send_to_hoptoad(data)
else
log :error, "Failure: #{response.class}", response
end
+
+ if response && response.respond_to?(:body)
+ error_id = response.body.match(%r{<error-id[^>]*>(.*?)</error-id>})
+ error_id[1] if error_id
+ end
end
private
View
29 lib/hoptoad_notifier/shared_tasks.rb
@@ -0,0 +1,29 @@
+namespace :hoptoad do
+ desc "Notify Hoptoad of a new deploy."
+ task :deploy => :environment do
+ require 'hoptoad_tasks'
+ HoptoadTasks.deploy(:rails_env => ENV['TO'],
+ :scm_revision => ENV['REVISION'],
+ :scm_repository => ENV['REPO'],
+ :local_username => ENV['USER'],
+ :api_key => ENV['API_KEY'])
+ end
+
+ task :log_stdout do
+ require 'logger'
+ RAILS_DEFAULT_LOGGER = Logger.new(STDOUT)
+ end
+
+ namespace :heroku do
+ desc "Install Heroku deploy notifications addon"
+ task :add_deploy_notification => [:environment] do
+ heroku_api_key = `heroku console 'puts ENV[%{HOPTOAD_API_KEY}]' | head -n 1`.strip
+ heroku_rails_env = `heroku console 'puts RAILS_ENV' | head -n 1`.strip
+
+ command = %Q(heroku addons:add deployhooks:http url="http://hoptoadapp.com/deploys.txt?deploy[rails_env]=#{heroku_rails_env}&api_key=#{heroku_api_key}")
+
+ puts "\nRunning:\n#{command}\n"
+ puts `#{command}`
+ end
+ end
+end
View
18 lib/hoptoad_notifier/tasks.rb
@@ -1,21 +1,7 @@
require 'hoptoad_notifier'
+require File.join(File.dirname(__FILE__), 'shared_tasks')
namespace :hoptoad do
- desc "Notify Hoptoad of a new deploy."
- task :deploy => :environment do
- require 'hoptoad_tasks'
- HoptoadTasks.deploy(:rails_env => ENV['TO'],
- :scm_revision => ENV['REVISION'],
- :scm_repository => ENV['REPO'],
- :local_username => ENV['USER'],
- :api_key => ENV['API_KEY'])
- end
-
- task :log_stdout do
- require 'logger'
- RAILS_DEFAULT_LOGGER = Logger.new(STDOUT)
- end
-
desc "Verify your gem installation by sending a test exception to the hoptoad service"
task :test => ['hoptoad:log_stdout', :environment] do
RAILS_DEFAULT_LOGGER.level = Logger::DEBUG
@@ -89,7 +75,7 @@ def logger
class HoptoadVerificationController < ApplicationController; end
puts 'Processing request.'
- request = ActionController::TestRequest.new
+ request = ActionController::TestRequest.new("REQUEST_URI" => "/hoptoad_verification_controller")
response = ActionController::TestResponse.new
HoptoadVerificationController.new.process(request, response)
end
View
29 lib/hoptoad_notifier/user_informer.rb
@@ -0,0 +1,29 @@
+module HoptoadNotifier
+ class UserInformer
+ def initialize(app)
+ @app = app
+ end
+
+ def replacement(with)
+ @replacement ||= HoptoadNotifier.configuration.user_information.gsub(/\{\{\s*error_id\s*\}\}/, with.to_s)
+ end
+
+ def call(env)
+ response = @app.call(env)
+ if env['hoptoad.error_id']
+ new_response = []
+ original_content_length = 0
+ modified_content_length = 0
+ response[2].each do |chunk|
+ original_content_length += chunk.length
+ new_response << chunk.to_s.gsub("<!-- HOPTOAD ERROR -->", replacement(env['hoptoad.error_id']))
+ modified_content_length += new_response.last.length
+ end
+ response[1]['Content-Length'] = modified_content_length.to_s
+ response[2] = new_response
+ end
+ response
+ end
+ end
+end
+
View
2  lib/hoptoad_notifier/version.rb
@@ -1,3 +1,3 @@
module HoptoadNotifier
- VERSION = "2.3.3".freeze
+ VERSION = "2.4.5".freeze
end
View
25 lib/rails/generators/hoptoad/hoptoad_generator.rb
@@ -14,6 +14,7 @@ def install
ensure_plugin_is_not_present
append_capistrano_hook
generate_initializer unless api_key_configured?
+ determine_api_key if heroku?
test_hoptoad
end
@@ -55,6 +56,30 @@ def generate_initializer
template 'initializer.rb', 'config/initializers/hoptoad.rb'
end
+ def determine_api_key
+ puts "Attempting to determine your API Key from Heroku..."
+ ENV['HOPTOAD_API_KEY'] = heroku_api_key
+ if ENV['HOPTOAD_API_KEY'].blank?
+ puts "... Failed."
+ puts "WARNING: We were unable to detect the Hoptoad API Key from your Heroku environment."
+ puts "Your Heroku application environment may not be configured correctly."
+ exit 1
+ else
+ puts "... Done."
+ puts "Heroku's Hoptoad API Key is '#{ENV['HOPTOAD_API_KEY']}'"
+ end
+ end
+
+ def heroku_api_key
+ `heroku console 'puts ENV[%{HOPTOAD_API_KEY}]'`.split("\n").first
+ end
+
+ def heroku?
+ options[:heroku] ||
+ system("grep HOPTOAD_API_KEY config/initializers/hoptoad.rb") ||
+ system("grep HOPTOAD_API_KEY config/environment.rb")
+ end
+
def api_key_configured?
File.exists?('config/initializers/hoptoad.rb')
end
View
19 lib/templates/javascript_notifier.erb
@@ -1,6 +1,13 @@
-<script type="text/javascript" src="http://<%= host %>/javascripts/notifier.js"></script>
-<script type="text/javascript">
- Hoptoad.setKey('<%= api_key %>');
- Hoptoad.setHost('<%= host %>');
- Hoptoad.setEnvironment('<%= environment %>');
-</script>
+<%= javascript_tag %Q{
+ var notifierJsScheme = (("https:" == document.location.protocol) ? "https://" : "http://");
+ document.write(unescape("%3Cscript src='" + notifierJsScheme + "#{host}/javascripts/notifier.js' type='text/javascript'%3E%3C/script%3E"));
+ }
+%>
+
+<%= javascript_tag %Q{
+ Hoptoad.setKey('#{api_key}');
+ Hoptoad.setHost('#{host}');
+ Hoptoad.setEnvironment('#{environment}');
+ Hoptoad.setErrorDefaults({ url: "#{escape_javascript url}", component: "#{controller_name}", action: "#{action_name}" });
+ }
+%>
View
2  test/catcher_test.rb
@@ -25,6 +25,8 @@ def build_controller_class(&definition)
def assert_sent_hash(hash, xpath)
hash.each do |key, value|
+ next if key.match(/^hoptoad\./) # We added this key.
+
element_xpath = "#{xpath}/var[@key = '#{key}']"
if value.respond_to?(:to_hash)
assert_sent_hash value.to_hash, element_xpath
View
11 test/configuration_test.rb
@@ -29,7 +29,6 @@ class ConfigurationTest < Test::Unit::TestCase
HoptoadNotifier::Configuration::IGNORE_DEFAULT
assert_config_default :development_lookup, true
assert_config_default :framework, 'Standalone'
- assert_config_default :js_notifier, false
end
should "provide default values for secure connections" do
@@ -85,7 +84,7 @@ class ConfigurationTest < Test::Unit::TestCase
:http_read_timeout, :ignore, :ignore_by_filters, :ignore_user_agent,
:notifier_name, :notifier_url, :notifier_version, :params_filters,
:project_root, :port, :protocol, :proxy_host, :proxy_pass, :proxy_port,
- :proxy_user, :secure, :development_lookup, :js_notifier].each do |option|
+ :proxy_user, :secure, :development_lookup].each do |option|
assert_equal config[option], hash[option], "Wrong value for #{option}"
end
end
@@ -108,6 +107,14 @@ class ConfigurationTest < Test::Unit::TestCase
assert_equal [], config.environment_filters
end
+ should "warn when attempting to write js_notifier" do
+ config = HoptoadNotifier::Configuration.new
+ config.
+ expects(:warn).
+ with(regexp_matches(/deprecated/i))
+ config.js_notifier = true
+ end
+
should "allow ignored user agents to be appended" do
assert_appends_value :ignore_user_agent
end
View
11 test/helper.rb
@@ -1,7 +1,13 @@
require 'test/unit'
require 'rubygems'
-gem 'jferris-mocha', '>= 0.9.5.0.1241126838'
+gem "activesupport", "= 2.3.8"
+gem "activerecord", "= 2.3.8"
+gem "actionpack", "= 2.3.8"
+gem "nokogiri", "= 1.4.3.1"
+gem "shoulda", "= 2.11.3"
+gem 'bourne', '>= 1.0'
+gem "sham_rack", "~> 1.3.0"
$LOAD_PATH << File.join(File.dirname(__FILE__), *%w[.. vendor ginger lib])
$LOAD_PATH << File.expand_path(File.join(File.dirname(__FILE__), "..", "lib"))
@@ -11,6 +17,7 @@
require 'ginger'
+
require 'action_controller'
require 'action_controller/test_process'
require 'active_record'
@@ -18,6 +25,8 @@
require 'active_support'
require 'nokogiri'
require 'rack'
+require 'bourne'
+require 'sham_rack'
require "hoptoad_notifier"
View
52 test/javascript_notifier_test.rb
@@ -0,0 +1,52 @@
+require File.dirname(__FILE__) + '/helper'
+require 'hoptoad_notifier/rails/javascript_notifier'
+require 'ostruct'
+
+class JavascriptNotifierTest < Test::Unit::TestCase
+ module FakeRenderer
+ def javascript_tag(text)
+ "<script>#{text}</script>"
+ end
+ def escape_javascript(text)
+ "ESC#{text}ESC"
+ end
+ end
+
+ class FakeController
+ def self.helper_method(*args)
+ end
+
+ include HoptoadNotifier::Rails::JavascriptNotifier
+
+ def action_name
+ "action"
+ end
+
+ def controller_name
+ "controller"
+ end
+
+ def request
+ @request ||= OpenStruct.new
+ end
+
+ def render_to_string(options)
+ context = OpenStruct.new(options[:locals])
+ context.extend(FakeRenderer)
+ context.instance_eval do
+ erb = ERB.new(IO.read(options[:file]))
+ erb.result(binding)
+ end
+ end
+ end
+
+ should "make sure escape_javacript is called on the request.url" do
+ HoptoadNotifier.configure do
+ end
+ controller = FakeController.new
+ controller.request.url = "bad_javascript"
+ assert controller.send(:hoptoad_javascript_notifier)['"ESCbad_javascriptESC"']
+ assert ! controller.send(:hoptoad_javascript_notifier)['"bad_javascript"']
+ end
+end
+
View
45 test/notice_test.rb
@@ -168,6 +168,16 @@ def stub_request(attrs = {})
assert_filters_hash(:session_data)
end
+ should "remove rack.request.form_vars" do
+ original = {
+ "rack.request.form_vars" => "story%5Btitle%5D=The+TODO+label",
+ "abc" => "123"
+ }
+
+ notice = build_notice(:cgi_data => original)
+ assert_equal({"abc" => "123"}, notice.cgi_data)
+ end
+
context "a Notice turned into XML" do
setup do
HoptoadNotifier.configure do |config|
@@ -300,29 +310,20 @@ def stub_request(attrs = {})
end
end
- should "ignore RecordNotFound error by default" do
- notice = build_notice(:error_class => 'ActiveRecord::RecordNotFound')
- assert notice.ignore?
- end
-