loom-exceptions-rails-plugin 2.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.
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2008 [name of plugin creator]
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,31 @@
1
+ h2. Loom
2
+
3
+ This plugin provides exception reporting for "Loom":http://loomapp.com.
4
+
5
+ h2. Usage
6
+
7
+ You must sign up to Loom to use this plugin. Install as a gem or a plugin.
8
+
9
+ h3. Installation
10
+
11
+ <code>script/plugin install git://github.com/alexyoung/loom-exceptions-rails-plugin.git</code>
12
+
13
+ Add this to <code>config/initializers/loom.rb</code>
14
+
15
+ <pre><code>
16
+ Helicoid::Loom.configure do |config|
17
+ config.api_key = 'xxx'
18
+ config.server = 'http://loomapp.com'
19
+ end
20
+ </code></pre>
21
+
22
+ The <code>server</code> option can be used with the open source version of Loom.
23
+
24
+ If you use <code>rescue_action_in_public</code> use <code>rescue_action_in_public_without_loom</code> to stop overloading Loom's reporter.
25
+
26
+ h2. Credits
27
+
28
+ * Created by Alex Young for Helicoid Limited (helicoid.net)
29
+ * Advice and additional development by Gabriel Gironda (annealer.org)
30
+
31
+ Copyright (c) 2008-2009 Helicoid Limited, released under the MIT license
@@ -0,0 +1,22 @@
1
+ require 'rake'
2
+ require 'rake/testtask'
3
+ require 'rake/rdoctask'
4
+
5
+ desc 'Default: run unit tests.'
6
+ task :default => :test
7
+
8
+ desc 'Test the loom plugin.'
9
+ Rake::TestTask.new(:test) do |t|
10
+ t.libs << 'lib'
11
+ t.pattern = 'test/**/*_test.rb'
12
+ t.verbose = true
13
+ end
14
+
15
+ desc 'Generate documentation for the loom plugin.'
16
+ Rake::RDocTask.new(:rdoc) do |rdoc|
17
+ rdoc.rdoc_dir = 'rdoc'
18
+ rdoc.title = 'Loom'
19
+ rdoc.options << '--line-numbers' << '--inline-source'
20
+ rdoc.rdoc_files.include('README')
21
+ rdoc.rdoc_files.include('lib/**/*.rb')
22
+ end
data/init.rb ADDED
@@ -0,0 +1,4 @@
1
+ require 'loom'
2
+ require 'loom_exception'
3
+
4
+ Helicoid::Loom.enable
@@ -0,0 +1 @@
1
+ # Install hook code here
@@ -0,0 +1,65 @@
1
+ module Helicoid
2
+ module Loom
3
+ class << self
4
+ attr_accessor :api_key, :server, :before_action, :user_id
5
+
6
+ def enable
7
+ ActionController::Base.class_eval do
8
+ include Reporter
9
+ end
10
+ end
11
+
12
+ def configure
13
+ yield self
14
+
15
+ self.server ||= 'http://loomapp.com'
16
+
17
+ if defined?(ActionController::Base) && !ActionController::Base.include?(Helicoid::Loom::Reporter)
18
+ enable
19
+ end
20
+ end
21
+ end
22
+
23
+ module Reporter
24
+ def self.included(base)
25
+ base.send(:alias_method, :rescue_action_in_public_without_loom, :rescue_action_in_public)
26
+ base.send(:alias_method, :rescue_action_in_public, :send_to_loom)
27
+ end
28
+
29
+ def send_to_loom(exception)
30
+ raise if local_request?
31
+
32
+ send(Helicoid::Loom.before_action) if Helicoid::Loom.before_action
33
+
34
+ user_id = case Helicoid::Loom.user_id
35
+ when Proc
36
+ Helicoid::Loom.user_id.bind(self).call
37
+ when Symbol, String
38
+ send Helicoid::Loom.user_id
39
+ end
40
+
41
+ LoomException.log Helicoid::Loom.server, Helicoid::Loom.api_key do |loom|
42
+ loom.session = session.data
43
+ loom.remote_ip = request.remote_ip
44
+ loom.exception = exception
45
+ loom.cookies = request.cookies
46
+ loom.request_parameters = request.parameters
47
+ loom.url = request.request_uri
48
+ loom.user_id = user_id
49
+ end
50
+
51
+ rescue_action_in_public_without_loom exception
52
+ end
53
+ end
54
+
55
+ module ClassMethods
56
+ def logger
57
+ ActiveRecord::Base.logger
58
+ end
59
+
60
+ def enable_loom(options = {})
61
+ logger.warn "enable_loom has been removed. Please use config/initializers/loom.rb or call Helicoid::Loom.configure."
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,68 @@
1
+ require 'pp'
2
+ require 'net/http'
3
+
4
+ class LoomException
5
+ attr_accessor :session, :cookies, :request_parameters, :url, :user_id, :exception, :remote_ip
6
+
7
+ class LoomDown < Exception ; end
8
+ class LoomError < Exception ; end
9
+
10
+ def initialize(url, api_key)
11
+ @loom_login = { :url => url, :api_key => api_key }
12
+ end
13
+
14
+ def send_to_loom
15
+ response = post
16
+
17
+ if response.code.match /^2/
18
+ true
19
+ else
20
+ puts response.message
21
+ puts response.body
22
+ end
23
+ end
24
+
25
+ def self.log(url, api_key, &block)
26
+ loom = new url, api_key
27
+ yield loom
28
+ loom.send_to_loom
29
+ rescue LoomDown # TODO
30
+ # Timed out or Loom down. Log the error and optionally email the administrator.
31
+ rescue LoomError # TODO
32
+ # We sent an invalid request. Log the error and optionally email the administrator.
33
+ rescue Exception # TODO
34
+ # Something else happened, log it. The user will be shown an error page so they
35
+ # can acknowledge the issue and continue using the application.
36
+ end
37
+
38
+ private
39
+ def post
40
+ url = URI.parse "#{@loom_login[:url]}/report/#{@loom_login[:api_key]}"
41
+
42
+ req = Net::HTTP::Post.new url.path
43
+ req.add_field 'Accept', 'application/x-www-form-urlencoded'
44
+ req.add_field 'Content-Type', 'application/x-www-form-urlencoded'
45
+ req.set_form_data({ :remote_exception => loom_parameters.to_yaml })
46
+
47
+ connection = Net::HTTP.new(url.host, url.port)
48
+ connection.request req
49
+ end
50
+
51
+ def loom_parameters
52
+ {
53
+ :title => "#{@exception.class}: #{@exception.to_s}",
54
+ :details => { 'session_variables' => @session.dup,
55
+ 'cookies' => @cookies.dup,
56
+ 'request_parameters' => @request_parameters.dup,
57
+ 'url' => @url,
58
+ 'user_id' => @user_id,
59
+ 'remote_ip' => @remote_ip,
60
+ 'stack_trace' => stack_trace }
61
+ }
62
+ end
63
+
64
+ def stack_trace
65
+ return '' unless @exception.backtrace
66
+ @exception.backtrace.join("\n")
67
+ end
68
+ end
@@ -0,0 +1,19 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{loom-exceptions-rails-plugin}
5
+ s.version = "2.0"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["Alex R. Young"]
9
+ s.date = %q{2009-07-18}
10
+ s.description = %q{Loom is a helpdesk web app which supports exception handling and notifications.}
11
+ s.email = %q{alex@alexyoung.org}
12
+ s.files = ["init.rb", "install.rb", "lib", "lib/loom.rb", "lib/loom_exception.rb", "loom-exceptions-rails-plugin.gemspec", "MIT-LICENSE", "Rakefile", "README.textile", "tasks", "tasks/loom_tasks.rake", "test", "test/exception_test.rb", "test/loom_test.rb", "uninstall.rb"]
13
+ s.has_rdoc = false
14
+ s.homepage = %q{http://loomapp.com}
15
+ s.require_paths = ["lib"]
16
+ s.rubygems_version = %q{1.3.0}
17
+ s.summary = %q{This gem provides exception notification handling for your Rails applications.}
18
+ end
19
+
@@ -0,0 +1,36 @@
1
+ # desc "Explaining what the task does"
2
+ # task :loom do
3
+ # # Task goes here
4
+ # end
5
+
6
+ namespace :loom do
7
+ desc "Sends a test exception so you can test your settings"
8
+ task :test do
9
+ require 'action_controller/test_process'
10
+
11
+ begin
12
+ require 'app/controllers/application_controller'
13
+ rescue LoadError
14
+ require 'app/controllers/application'
15
+ end
16
+
17
+ class ApplicationController
18
+ def test
19
+ puts "Connecting to server: #{Helicoid::Loom.server} with API key: #{Helicoid::Loom.api_key}"
20
+ raise "This is a test error notification"
21
+ end
22
+
23
+ def rescue_action(exception)
24
+ rescue_action_in_public exception
25
+ end
26
+ end
27
+
28
+ request = ActionController::TestRequest.new
29
+ response = ActionController::TestResponse.new
30
+
31
+ request.action = 'test'
32
+ request.request_uri = '/test'
33
+
34
+ ApplicationController.process request, response
35
+ end
36
+ end
File without changes
@@ -0,0 +1,68 @@
1
+ require 'rubygems'
2
+ require 'active_support'
3
+ require 'ostruct'
4
+ require 'test/unit'
5
+ require 'mocha'
6
+ require File.dirname(__FILE__) + '/../lib/loom'
7
+ require File.dirname(__FILE__) + '/../lib/loom_exception'
8
+
9
+ class LoomTest < Test::Unit::TestCase
10
+ # Replace this with your real tests.
11
+
12
+ def setup
13
+ stub_loom_api
14
+ end
15
+
16
+ def test_catches_exception
17
+ end
18
+
19
+ def test_posts_to_loom
20
+ exception = mock_loom_exception :exception => mock_exception
21
+ assert exception.send_to_loom
22
+ end
23
+
24
+ def test_posts_to_loom_with_nil_backtrace
25
+ exception = mock_loom_exception
26
+ assert exception.send_to_loom
27
+ end
28
+
29
+ def test_configure
30
+ Helicoid::Loom.configure do |config|
31
+ config.api_key = 'xxx'
32
+ end
33
+ assert_equal 'xxx', Helicoid::Loom.api_key
34
+ assert_equal 'http://loomapp.com', Helicoid::Loom.server
35
+ end
36
+
37
+ private
38
+
39
+ def mocked_response(options = {})
40
+ OpenStruct.new :code => '200'
41
+ end
42
+
43
+ def stub_loom_api
44
+ Net::HTTP.any_instance.stubs(:request).returns mocked_response
45
+ end
46
+
47
+ def mock_exception
48
+ exception = nil
49
+ begin
50
+ 1 / 0
51
+ rescue Exception => e
52
+ exception = e
53
+ end
54
+ exception
55
+ end
56
+
57
+ def mock_loom_exception(options = {})
58
+ exception = LoomException.new 'helicoid', 'xxx'
59
+ exception.session = OpenStruct.new :user_id => '1'
60
+ exception.cookies = [{ :var_1 => [1, 2, 3, 4], :var_2 => { :a => 'b' }}]
61
+ exception.request_parameters = []
62
+ exception.url = 'http://example.com'
63
+ exception.user_id = '1'
64
+ exception.exception = options[:exception] || ZeroDivisionError.new
65
+ exception.remote_ip = '127.0.0.1'
66
+ exception
67
+ end
68
+ end
@@ -0,0 +1 @@
1
+ # Uninstall hook code here
metadata ADDED
@@ -0,0 +1,66 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: loom-exceptions-rails-plugin
3
+ version: !ruby/object:Gem::Version
4
+ version: "2.0"
5
+ platform: ruby
6
+ authors:
7
+ - Alex R. Young
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-07-18 00:00:00 +01:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: Loom is a helpdesk web app which supports exception handling and notifications.
17
+ email: alex@alexyoung.org
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files: []
23
+
24
+ files:
25
+ - init.rb
26
+ - install.rb
27
+ - lib/loom.rb
28
+ - lib/loom_exception.rb
29
+ - loom-exceptions-rails-plugin.gemspec
30
+ - MIT-LICENSE
31
+ - Rakefile
32
+ - README.textile
33
+ - tasks/loom_tasks.rake
34
+ - test/exception_test.rb
35
+ - test/loom_test.rb
36
+ - uninstall.rb
37
+ has_rdoc: false
38
+ homepage: http://loomapp.com
39
+ licenses: []
40
+
41
+ post_install_message:
42
+ rdoc_options: []
43
+
44
+ require_paths:
45
+ - lib
46
+ required_ruby_version: !ruby/object:Gem::Requirement
47
+ requirements:
48
+ - - ">="
49
+ - !ruby/object:Gem::Version
50
+ version: "0"
51
+ version:
52
+ required_rubygems_version: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: "0"
57
+ version:
58
+ requirements: []
59
+
60
+ rubyforge_project:
61
+ rubygems_version: 1.3.4
62
+ signing_key:
63
+ specification_version: 3
64
+ summary: This gem provides exception notification handling for your Rails applications.
65
+ test_files: []
66
+