Skip to content

Commit

Permalink
Merge branch 'master' of git@github.com:thoughtbot/hoptoad_notifier
Browse files Browse the repository at this point in the history
  • Loading branch information
Jon Yurek committed Nov 19, 2008
2 parents 9b00fbd + bdd26b3 commit 3805660
Show file tree
Hide file tree
Showing 4 changed files with 145 additions and 7 deletions.
44 changes: 42 additions & 2 deletions README
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ This is the notifier plugin for integrating apps with Hoptoad.
When an uncaught exception occurs, HoptoadNotifier will POST the relevant data
to the Hoptoad server specified in your environment.


INSTALLATION
------------

Expand Down Expand Up @@ -78,6 +77,43 @@ controller, you can do something like this:
The #notify_hoptoad call will send the notice over to hoptoad for later
analysis.

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}",
:request => { :params => 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 about the error itself. As for a hash, these are the keys you should pass:

* :error_class – Use this to group similar errors together. When Hoptoad catches an exception it sends the class name of that exception object.
* :error_message – This is the title of the error you see in the errors list. For exceptions it is "#{exception.class.name}: #{exception.message}"
* :request – While there are several ways to send additional data to Hoptoad, passing a Hash with :params key as :request as in the example above is the most common use case. When Hoptoad catches an exception in a controller, the actual HTTP client request is being sent using this key.

Hoptoad merges the hash you pass with these default options:

def default_notice_options
{
:api_key => HoptoadNotifier.api_key,
:error_message => 'Notification',
:backtrace => caller,
:request => {},
:session => {},
:environment => ENV.to_hash
}
end

You can override any of those parameters.

FILTERING

Expand Down Expand Up @@ -110,7 +146,6 @@ To ignore *only* certain errors (and override the defaults), use the
config.ignore_only = [ActiveRecord::IgnoreThisError]
end


TESTING

When you run your tests, you might notice that the hoptoad service is recording
Expand All @@ -123,3 +158,8 @@ errors are not reported while running tests.
# do nothing.
end
end

THANKS

Thanks to Eugene Bolshakov for the excellent write-up on GOING BEYOND EXCEPTIONS, which we have included above.

18 changes: 15 additions & 3 deletions lib/hoptoad_notifier.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
require 'net/http'
require 'net/https'
require 'rubygems'
require 'active_support'

# Plugin for applications to automatically post errors to the Hoptoad of their choice.
module HoptoadNotifier
Expand Down Expand Up @@ -58,6 +61,13 @@ def environment_filters
end

# Call this method to modify defaults in your initializers.
#
# HoptoadNotifier.configure do |config|
# config.api_key = '1234567890abcdef'
# config.secure = false
# end
#
# NOTE: secure connections are not yet supported.
def configure
yield self
end
Expand Down Expand Up @@ -105,8 +115,10 @@ def notify notice = {}
end

filter_backtrace do |line|
Gem.path.inject(line) do |line, path|
line.gsub(/#{path}/, "[GEM_ROOT]")
if defined?(Gem)
Gem.path.inject(line) do |line, path|
line.gsub(/#{path}/, "[GEM_ROOT]")
end
end
end

Expand Down Expand Up @@ -217,7 +229,7 @@ def send_to_hoptoad data #:nodoc:
}
http.read_timeout = 5 # seconds
http.open_timeout = 2 # seconds
# http.use_ssl = HoptoadNotifier.secure
http.use_ssl = !!HoptoadNotifier.secure
response = begin
http.post(url.path, stringify_keys(data).to_yaml, headers)
rescue TimeoutError => e
Expand Down
28 changes: 28 additions & 0 deletions script/integration_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#!/usr/bin/env ruby

# This file must _not_ end in test.rb, or it will get run every time.
require File.join(File.dirname(__FILE__), "..", "lib", "hoptoad_notifier")

#fail ARGV.inspect
fail "Please supply an API Key as the first argument" if ARGV.empty?

RAILS_ENV = "production"
RAILS_ROOT = "./"

host = ARGV[1]
host ||= "hoptoadapp.com"

HoptoadNotifier.configure do |config|
config.host = host
config.api_key = ARGV.first
end

exception = begin
raise 'Testing hoptoad notifier. If you can see this, it works.'
rescue => foo
foo
end

puts "Sending notification to project with key #{ARGV.first}"
HoptoadNotifier.notify(exception)

62 changes: 60 additions & 2 deletions test/hoptoad_notifier_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@
require 'action_controller'
require 'action_controller/test_process'
require 'active_record'
require 'net/http'
require 'net/https'
require File.join(File.dirname(__FILE__), "..", "lib", "hoptoad_notifier")

RAILS_ROOT = File.join( File.dirname(__FILE__), "rails_root" )
Expand Down Expand Up @@ -355,6 +353,66 @@ def rescue_action e
@sender.stubs(:public_environment?).returns(true)
end

context "when stubbing out Net::HTTP" do
setup do
@body = 'body'
@response = stub(:body => @body)
@http = stub(:post => @response, :read_timeout= => nil, :open_timeout= => nil, :use_ssl= => nil)
@sender.stubs(:logger).returns(stub(:error => nil, :info => nil))
Net::HTTP.stubs(:start).yields(@http)
HoptoadNotifier.port = nil
HoptoadNotifier.host = nil
end

context "on notify" do
setup { HoptoadNotifier.notify(@exception) }

before_should "post to the right url for non-ssl" do
HoptoadNotifier.secure = false
url = "http://hoptoadapp.com:80/notices/"
uri = URI.parse(url)
URI.expects(:parse).with(url).returns(uri)
@http.expects(:post).with(uri.path, anything, anything).returns(@response)
end

before_should "post to the right path" do
@http.expects(:post).with("/notices/", anything, anything).returns(@response)
end

before_should "call send_to_hoptoad" do
@sender.expects(:send_to_hoptoad)
end

before_should "set the open timeout to 2 seconds" do
@http.expects(:open_timeout=).with(2)
end

before_should "set the read timeout to 5 seconds" do
@http.expects(:read_timeout=).with(5)
end

before_should "connect to the right port for ssl" do
HoptoadNotifier.secure = true
Net::HTTP.expects(:start).with("hoptoadapp.com", 443).yields(@http)
end

before_should "connect to the right port for non-ssl" do
HoptoadNotifier.secure = false
Net::HTTP.expects(:start).with("hoptoadapp.com", 80).yields(@http)
end

before_should "use ssl if secure" do
HoptoadNotifier.secure = true
@http.expects(:use_ssl=).with(true)
end

before_should "not use ssl if not secure" do
HoptoadNotifier.secure = nil
@http.expects(:use_ssl=).with(false)
end
end
end

should "send as if it were a normally caught exception" do
@sender.expects(:notify_hoptoad).with(@exception)
HoptoadNotifier.notify(@exception)
Expand Down

0 comments on commit 3805660

Please sign in to comment.