loom-exceptions-rails-plugin 2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
+