radiant-exception_notification-extension 0.8.1

Sign up to get free protection for your applications and to get access to all the features.
data/README ADDED
@@ -0,0 +1,68 @@
1
+ = EXCEPTION NOTIFICATION
2
+
3
+ Extends Radiant's error handling to include email notification and Radiant-
4
+ managed error templates for exceptions raised in other extensions. Based on
5
+ Jamis Buck's original Rails exception notifier.
6
+
7
+ = USAGE
8
+
9
+ 1. Enable ActionMailer
10
+
11
+ Locate +config.frameworks -= [ :action_mailer ]+ in config/environment.rb.
12
+ Comment out this line, or remove action_mailer from the list of frameworks
13
+ you are skipping.
14
+
15
+ 2. Define the email addresses ExceptionNotifier should use
16
+
17
+ Set the following somewhere within your environment:
18
+
19
+ ExceptionNotifier.email_to = 'send@to.email'
20
+ ExceptionNotifier.email_from = 'sent@from.email'
21
+
22
+ 3. Create some error templates
23
+
24
+ Exception Notification adds an additional Page subclass called
25
+ InternalServerErrorPage. This and its existing sibling, FileNotFoundPage,
26
+ determine what gets rendered when an exception is raised. Create one of
27
+ each within your content tree. ExceptionNotification is aware of the
28
+ multi-site extension, so you can create individual error pages for
29
+ each site.
30
+
31
+ = NOTES
32
+
33
+ By default, your FileNotFound page will be rendered when the following
34
+ exceptions are caught:
35
+
36
+ * ActiveRecord::RecordNotFound
37
+ * ActionController::UnknownController
38
+ * ActionController::UnknownAction
39
+ * ActionController::RoutingError
40
+
41
+ All other errors will render with an InternalServerErrorPage. Both templates
42
+ are rendered even when running in development mode. If you'd like your stack
43
+ traces displayed (like dev mode in a standard Rails application,) set the
44
+ following somewhere within your environment:
45
+
46
+ Radiant::Config['debug?'] = true
47
+
48
+ ==============================================================================
49
+
50
+ Copyright (c) 2008 Digital Pulp, Inc.
51
+
52
+ Permission is hereby granted, free of charge, to any person obtaining a copy
53
+ of this software and associated documentation files (the "Software"), to deal
54
+ in the Software without restriction, including without limitation the rights
55
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
56
+ copies of the Software, and to permit persons to whom the Software is
57
+ furnished to do so, subject to the following conditions:
58
+
59
+ The above copyright notice and this permission notice shall be included in
60
+ all copies or substantial portions of the Software.
61
+
62
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
63
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
64
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
65
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
66
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
67
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
68
+ THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,120 @@
1
+ # I think this is the one that should be moved to the extension Rakefile template
2
+
3
+ # In rails 1.2, plugins aren't available in the path until they're loaded.
4
+ # Check to see if the rspec plugin is installed first and require
5
+ # it if it is. If not, use the gem version.
6
+
7
+ # Determine where the RSpec plugin is by loading the boot
8
+ unless defined? RADIANT_ROOT
9
+ ENV["RAILS_ENV"] = "test"
10
+ case
11
+ when ENV["RADIANT_ENV_FILE"]
12
+ require File.dirname(ENV["RADIANT_ENV_FILE"]) + "/boot"
13
+ when File.dirname(__FILE__) =~ %r{vendor/radiant/vendor/extensions}
14
+ require "#{File.expand_path(File.dirname(__FILE__) + "/../../../../../")}/config/boot"
15
+ else
16
+ require "#{File.expand_path(File.dirname(__FILE__) + "/../../../")}/config/boot"
17
+ end
18
+ end
19
+
20
+ require 'rake'
21
+ require 'rake/rdoctask'
22
+ require 'rake/testtask'
23
+
24
+ rspec_base = File.expand_path(RADIANT_ROOT + '/vendor/plugins/rspec/lib')
25
+ $LOAD_PATH.unshift(rspec_base) if File.exist?(rspec_base)
26
+ require 'spec/rake/spectask'
27
+ # require 'spec/translator'
28
+
29
+ # Cleanup the RADIANT_ROOT constant so specs will load the environment
30
+ Object.send(:remove_const, :RADIANT_ROOT)
31
+
32
+ extension_root = File.expand_path(File.dirname(__FILE__))
33
+
34
+ task :default => :spec
35
+ task :stats => "spec:statsetup"
36
+
37
+ desc "Run all specs in spec directory"
38
+ Spec::Rake::SpecTask.new(:spec) do |t|
39
+ t.spec_opts = ['--options', "\"#{extension_root}/spec/spec.opts\""]
40
+ t.spec_files = FileList['spec/**/*_spec.rb']
41
+ end
42
+
43
+ namespace :spec do
44
+ desc "Run all specs in spec directory with RCov"
45
+ Spec::Rake::SpecTask.new(:rcov) do |t|
46
+ t.spec_opts = ['--options', "\"#{extension_root}/spec/spec.opts\""]
47
+ t.spec_files = FileList['spec/**/*_spec.rb']
48
+ t.rcov = true
49
+ t.rcov_opts = ['--exclude', 'spec', '--rails']
50
+ end
51
+
52
+ desc "Print Specdoc for all specs"
53
+ Spec::Rake::SpecTask.new(:doc) do |t|
54
+ t.spec_opts = ["--format", "specdoc", "--dry-run"]
55
+ t.spec_files = FileList['spec/**/*_spec.rb']
56
+ end
57
+
58
+ [:models, :controllers, :views, :helpers].each do |sub|
59
+ desc "Run the specs under spec/#{sub}"
60
+ Spec::Rake::SpecTask.new(sub) do |t|
61
+ t.spec_opts = ['--options', "\"#{extension_root}/spec/spec.opts\""]
62
+ t.spec_files = FileList["spec/#{sub}/**/*_spec.rb"]
63
+ end
64
+ end
65
+
66
+ # Hopefully no one has written their extensions in pre-0.9 style
67
+ # desc "Translate specs from pre-0.9 to 0.9 style"
68
+ # task :translate do
69
+ # translator = ::Spec::Translator.new
70
+ # dir = RAILS_ROOT + '/spec'
71
+ # translator.translate(dir, dir)
72
+ # end
73
+
74
+ # Setup specs for stats
75
+ task :statsetup do
76
+ require 'code_statistics'
77
+ ::STATS_DIRECTORIES << %w(Model\ specs spec/models)
78
+ ::STATS_DIRECTORIES << %w(View\ specs spec/views)
79
+ ::STATS_DIRECTORIES << %w(Controller\ specs spec/controllers)
80
+ ::STATS_DIRECTORIES << %w(Helper\ specs spec/views)
81
+ ::CodeStatistics::TEST_TYPES << "Model specs"
82
+ ::CodeStatistics::TEST_TYPES << "View specs"
83
+ ::CodeStatistics::TEST_TYPES << "Controller specs"
84
+ ::CodeStatistics::TEST_TYPES << "Helper specs"
85
+ ::STATS_DIRECTORIES.delete_if {|a| a[0] =~ /test/}
86
+ end
87
+
88
+ namespace :db do
89
+ namespace :fixtures do
90
+ desc "Load fixtures (from spec/fixtures) into the current environment's database. Load specific fixtures using FIXTURES=x,y"
91
+ task :load => :environment do
92
+ require 'active_record/fixtures'
93
+ ActiveRecord::Base.establish_connection(RAILS_ENV.to_sym)
94
+ (ENV['FIXTURES'] ? ENV['FIXTURES'].split(/,/) : Dir.glob(File.join(RAILS_ROOT, 'spec', 'fixtures', '*.{yml,csv}'))).each do |fixture_file|
95
+ Fixtures.create_fixtures('spec/fixtures', File.basename(fixture_file, '.*'))
96
+ end
97
+ end
98
+ end
99
+ end
100
+ end
101
+
102
+ desc 'Generate documentation for the exception_handler extension.'
103
+ Rake::RDocTask.new(:rdoc) do |rdoc|
104
+ rdoc.rdoc_dir = 'rdoc'
105
+ rdoc.title = 'ExceptionHandlerExtension'
106
+ rdoc.options << '--line-numbers' << '--inline-source'
107
+ rdoc.rdoc_files.include('README')
108
+ rdoc.rdoc_files.include('lib/**/*.rb')
109
+ end
110
+
111
+ # For extensions that are in transition
112
+ desc 'Test the exception_handler extension.'
113
+ Rake::TestTask.new(:test) do |t|
114
+ t.libs << 'lib'
115
+ t.pattern = 'test/**/*_test.rb'
116
+ t.verbose = true
117
+ end
118
+
119
+ # Load any custom rakefiles for extension
120
+ Dir[File.dirname(__FILE__) + '/tasks/*.rake'].sort.each { |f| require f }
@@ -0,0 +1,35 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require 'pp'
3
+
4
+ class ExceptionNotifier < ActionMailer::Base
5
+
6
+ cattr_accessor :email_from, :email_to
7
+
8
+ self.template_root = File.join(File.dirname(__FILE__),"..","views")
9
+
10
+ def notification(exception, controller, request)
11
+ time = Time.new
12
+ from ExceptionNotifier.email_from
13
+ recipients ExceptionNotifier.email_to
14
+ subject "Rails exception on #{request.env["HTTP_HOST"]} \@ #{time.to_s :db} » #{exception.class.name} occurred in #{controller.controller_name}\##{controller.action_name}"
15
+ body :exception => exception, :request => request,
16
+ :controller => controller, :host => request.env["HTTP_HOST"],
17
+ :backtrace => sanitize_backtrace(exception.backtrace),
18
+ :rails_root => rails_root, :time => time
19
+
20
+ content_type 'text/plain'
21
+ end
22
+
23
+
24
+ private
25
+ # cribbed from the original Rails exception_notification plugin: http://github.com/rails/exception_notification/tree/master
26
+ def sanitize_backtrace(trace)
27
+ re = Regexp.new(/^#{Regexp.escape(rails_root)}/)
28
+ trace.map { |line| Pathname.new(line.gsub(re, "[RAILS_ROOT]")).cleanpath.to_s }
29
+ end
30
+
31
+ def rails_root
32
+ @rails_root ||= Pathname.new(RAILS_ROOT).cleanpath.to_s
33
+ end
34
+
35
+ end
@@ -0,0 +1,25 @@
1
+ # -*- encoding: utf-8 -*-
2
+ class InternalServerErrorPage < Page
3
+
4
+ description %{
5
+ An "Internal Server Error" page can be used to override the default
6
+ error page in the event that a request raises an unhandled exception.
7
+
8
+ To create an "Internal Server Error" error page for an entire Web site,
9
+ create a page that is a child of the root page and assign it
10
+ "Internal Server Error" page type.
11
+ }
12
+
13
+ def virtual?
14
+ true
15
+ end
16
+
17
+ def headers
18
+ { 'Status' => '500 Internal Server Error' }
19
+ end
20
+
21
+ def cache?
22
+ false
23
+ end
24
+
25
+ end
@@ -0,0 +1,34 @@
1
+ An exception occurred:
2
+
3
+ EXCEPTION:
4
+ <%= @exception.class.name %> in <%= @controller.controller_name %>#<%= @controller.action_name %>
5
+
6
+ ERROR:
7
+ <%= @exception.message %>
8
+
9
+ ----------------
10
+ Request Overview
11
+ ----------------
12
+ * URL: <%= @request.protocol %><%= @host %><%= @request.request_uri %>
13
+ * Parameters: <%= @request.parameters.inspect %>
14
+ * Session ID: <%= @request.session.instance_variable_get(:@session_id).inspect %>
15
+ * Session Data: <%= PP.pp(@request.session.instance_variable_get(:@data),"").gsub(/\n/, "\n ").strip %>
16
+
17
+ * Server : <%= `hostname`.chomp %>
18
+ * Process: <%= $$ %>
19
+ * Rails root: <%= @rails_root %>
20
+
21
+ * Date/Time: <%= @time.to_s :full %>
22
+
23
+ ---------------
24
+ Request Details
25
+ ---------------
26
+ <% max = @request.env.keys.max { |a,b| a.length <=> b.length } -%>
27
+ <% @request.env.keys.sort.each do |key| -%>
28
+ * <%= "%-*s: %s" % [max.length, key, @request.env[key].to_s.strip] %>
29
+ <% end -%>
30
+
31
+ ---------
32
+ Backtrace
33
+ ---------
34
+ <%= @backtrace.join("\n") %>
@@ -0,0 +1,19 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require_dependency 'application_controller'
3
+ require 'radiant-exception_notification-extension'
4
+
5
+ class ExceptionNotificationExtension < Radiant::Extension
6
+ version RadiantExceptionNotificationExtension::VERSION
7
+ description "Adds exception notification with Radiant-managed error pages"
8
+ url "http://github.com/digitalpulp"
9
+
10
+ def activate
11
+ ApplicationController.send :include, ExceptionNotification
12
+ Page.send(:include, ExceptionNotification::PageExtensions)
13
+ InternalServerErrorPage # instantiate class within Page.descendants
14
+ end
15
+
16
+ def deactivate
17
+ end
18
+
19
+ end
@@ -0,0 +1,61 @@
1
+ # -*- encoding: utf-8 -*-
2
+ module ExceptionNotification
3
+
4
+ ERROR_TYPES = {404 => FileNotFoundPage, 500 => InternalServerErrorPage}
5
+
6
+ def self.included(base)
7
+ base.class_eval do
8
+ alias_method_chain :rescue_action_in_public, :notification
9
+ alias_method_chain :rescue_action_locally, :template
10
+ end
11
+ end
12
+
13
+ def rescue_action_in_public_with_notification(exception)
14
+ case exception
15
+ when ActiveRecord::RecordNotFound, ActionController::UnknownController, ActionController::UnknownAction, ActionController::RoutingError
16
+ status_404(request)
17
+ else
18
+ status_500(request)
19
+ ExceptionNotifier.deliver_notification(exception, self, request)
20
+ end
21
+ end
22
+
23
+ def rescue_action_locally_with_template(exception)
24
+ unless Radiant::Config['debug?']
25
+ case exception
26
+ when ActiveRecord::RecordNotFound, ActionController::UnknownController, ActionController::UnknownAction, ActionController::RoutingError
27
+ status_404(request)
28
+ else
29
+ status_500(request)
30
+ ExceptionNotifier.deliver_notification(exception, self, request)
31
+ end
32
+ else
33
+ rescue_action_locally_without_template exception
34
+ end
35
+ end
36
+
37
+ private
38
+
39
+ def status_404(request = generic_request)
40
+ headers["Status"] = "404 Not Found"
41
+ page = Page.find_error_page(404)
42
+ page.request = request
43
+ response.body = page.render
44
+ end
45
+
46
+ def status_500(request = generic_request)
47
+ headers["Status"] = "500 Internal Server Error"
48
+ if page = Page.find_error_page(500)
49
+ page.request = request
50
+ response.body = page.render
51
+ else
52
+ response.body = "500 Internal Server Error. An exception occured while processing your request. Additionally, a custom Radiant managed 500 page was not found."
53
+ end
54
+ end
55
+
56
+ def generic_request
57
+ g = ActionController::AbstractRequest.new
58
+ g.relative_url_root = "/"
59
+ end
60
+
61
+ end
@@ -0,0 +1,34 @@
1
+ # -*- encoding: utf-8 -*-
2
+ module ExceptionNotification
3
+ module PageExtensions
4
+
5
+ def self.included(base)
6
+ base.extend(ClassMethods)
7
+ end
8
+
9
+ def find_error_page(type)
10
+ return nil unless page_class = ExceptionNotification::ERROR_TYPES[type]
11
+ if self.class_name == page_class.name
12
+ return self
13
+ else
14
+ children.each do |child|
15
+ found = child.find_error_page(type)
16
+ return found if found
17
+ end
18
+ end
19
+ nil
20
+ end
21
+
22
+ module ClassMethods
23
+ def find_error_page(type)
24
+ root = find_by_parent_id(nil)
25
+ if respond_to?(:current_site) && current_site
26
+ root = current_site.homepage
27
+ end
28
+ raise Page::MissingRootPageError unless root
29
+ root.find_error_page(type)
30
+ end
31
+ end
32
+
33
+ end
34
+ end
@@ -0,0 +1,4 @@
1
+ # -*- encoding: utf-8 -*-
2
+ module RadiantExceptionNotificationExtension
3
+ VERSION = '0.8.1'
4
+ end
@@ -0,0 +1,12 @@
1
+ # -*- encoding: utf-8 -*-
2
+ namespace :radiant do
3
+ namespace :extensions do
4
+ namespace :exception_notification do
5
+
6
+ # stubs for script/extension install
7
+ task :migrate
8
+ task :update
9
+
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,24 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path('../lib', __FILE__)
3
+ require 'radiant-exception_notification-extension'
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = 'radiant-exception_notification-extension'
7
+ s.version = RadiantExceptionNotificationExtension::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ['Josh French']
10
+ s.email = ['josh@vitamin-j.com']
11
+ s.homepage = 'http://github.com/digitalpulp'
12
+ s.summary = %q{Exception notification extension for Radiant CMS}
13
+ s.description = %q{Adds exception notification with Radiant-managed error pages}
14
+
15
+ s.files = `git ls-files`.split("\n")
16
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
17
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
18
+ s.require_paths = ["lib"]
19
+
20
+ s.post_install_message = %{
21
+ Add this to your radiant project with:
22
+ config.gem 'radiant-exception-notification', :version => '#{RadiantExceptionNotificationExtension::VERSION}'
23
+ }
24
+ end
@@ -0,0 +1,56 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.dirname(__FILE__) + "/../test_helper"
3
+
4
+ class ExceptionNotificationTest < Test::Unit::TestCase
5
+
6
+ def setup
7
+ @controller = SiteController.new
8
+ class << @controller
9
+ def rescue_action(e)
10
+ rescue_action_in_public(e)
11
+ end
12
+ end
13
+ @request = ActionController::TestRequest.new
14
+ @response = ActionController::TestResponse.new
15
+ ActionController::Base.consider_all_requests_local = false
16
+ ExceptionNotifier.stubs(:deliver_notification)
17
+ end
18
+
19
+ def teardown
20
+ ActionController::Base.consider_all_requests_local = true
21
+ end
22
+
23
+ def test_module_inclusion
24
+ assert ApplicationController.included_modules.include?(ExceptionNotification)
25
+ end
26
+
27
+ def test_rescue_action_in_public_should_render_when_404
28
+ exception = ActiveRecord::RecordNotFound.new
29
+ ExceptionNotifier.expects(:deliver_notification).never
30
+ @controller.expects(:show_page).raises(exception)
31
+ Page.expects(:find_error_page).with(404).returns(mock(:render => '404 template', :request= => @request))
32
+ @response.expects(:body=).with('404 template')
33
+ get :show_page, :url => "/"
34
+ assert_response :missing
35
+ end
36
+
37
+ def test_rescue_action_in_public_should_send_notification_when_500
38
+ exception = NoMethodError.new
39
+ @controller.expects(:show_page).raises(exception)
40
+ ExceptionNotifier.expects(:deliver_notification)
41
+ Page.expects(:find_error_page).with(500).returns(mock(:render => '500 template', :request= => @request))
42
+ @response.expects(:body=).with('500 template')
43
+ get :show_page, :url => "/"
44
+ assert_response :error
45
+ end
46
+
47
+ def test_rendered_page_has_access_to_request
48
+ url = PagePart.new(:name => 'body', :content => '<r:url/>')
49
+ page = Page.new(:parts => [url], :slug => '/bogus-url')
50
+ @controller.expects(:show_page).raises(NoMethodError.new)
51
+ Page.stubs(:find_error_page).with(500).returns(page)
52
+ get :show_page
53
+ assert_match(/bogus-url/, @response.body)
54
+ end
55
+
56
+ end
@@ -0,0 +1,10 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require 'test/unit'
3
+ require 'rubygems'
4
+ require 'mocha'
5
+ # Load the environment
6
+ unless defined? RADIANT_ROOT
7
+ ENV["RAILS_ENV"] = "test"
8
+ require "#{File.expand_path(File.dirname(__FILE__) + "/../../../../")}/config/environment"
9
+ end
10
+ require "#{RADIANT_ROOT}/test/test_helper"
@@ -0,0 +1,51 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.dirname(__FILE__) + "/../test_helper"
3
+
4
+ class ExceptionNotifierPageTest < Test::Unit::TestCase
5
+
6
+ def setup
7
+ create_page(Page) do |root|
8
+ create_page(FileNotFoundPage, :parent_id => root.id) do |filenotfound|
9
+ create_page(InternalServerErrorPage, :parent_id => filenotfound.id)
10
+ end
11
+ end
12
+ end
13
+
14
+ ### Class methods ###
15
+
16
+ def test_should_return_a_direct_descendent
17
+ assert_equal @file_not_found_page, Page.find_error_page(404)
18
+ end
19
+
20
+ def test_should_return_a_distant_descendent
21
+ assert_equal @internal_server_error_page, Page.find_error_page(500)
22
+ end
23
+
24
+ def test_should_return_nil_if_no_error_page_defined
25
+ assert_nil Page.find_error_page(501)
26
+ end
27
+
28
+ ### Instance methods ###
29
+
30
+ def test_should_find_self
31
+ assert_equal @file_not_found_page, @file_not_found_page.find_error_page(404)
32
+ end
33
+
34
+ def test_should_find_child
35
+ assert_equal @internal_server_error_page, @file_not_found_page.find_error_page(500)
36
+ end
37
+
38
+ def test_should_return_nil_if_neither_self_nor_child
39
+ assert_nil @internal_server_error_page.find_error_page(404)
40
+ end
41
+
42
+ private
43
+
44
+ def create_page(klass,attrs={})
45
+ name = klass.name.underscore
46
+ attrs.merge!(:title => name, :slug => name, :breadcrumb => name)
47
+ page = instance_variable_set("@#{name}", klass.create(attrs))
48
+ yield page if block_given?
49
+ end
50
+
51
+ end
@@ -0,0 +1,32 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.dirname(__FILE__) + "/../test_helper"
3
+
4
+ class DummyController < ApplicationController; end
5
+
6
+ class ExceptionNotifierTest < Test::Unit::TestCase
7
+
8
+ def setup
9
+ ActionMailer::Base.deliveries = []
10
+ ActionMailer::Base.delivery_method = :test
11
+ ActionMailer::Base.perform_deliveries = true
12
+
13
+ @request = ActionController::TestRequest.new
14
+ @request.request_uri = "/foo/bar/baz"
15
+
16
+ @exception = NoMethodError.new
17
+
18
+ ExceptionNotifier.email_from ||= 'from@digitalpulp.com'
19
+ ExceptionNotifier.email_to ||= 'to@digitalpulp.com'
20
+ end
21
+
22
+ def test_notification
23
+ @exception.set_backtrace(caller)
24
+ response = ExceptionNotifier.create_notification(@exception, DummyController.new, @request)
25
+
26
+ assert_match %r{#{@exception.class.name}}, response.body
27
+ assert_match %r{#{@request.request_uri}}, response.body
28
+
29
+ assert_equal ExceptionNotifier.email_from, response.from.first
30
+ assert_equal ExceptionNotifier.email_to, response.to.first
31
+ end
32
+ end
metadata ADDED
@@ -0,0 +1,85 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: radiant-exception_notification-extension
3
+ version: !ruby/object:Gem::Version
4
+ hash: 61
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 8
9
+ - 1
10
+ version: 0.8.1
11
+ platform: ruby
12
+ authors:
13
+ - Josh French
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-11-10 00:00:00 +00:00
19
+ default_executable:
20
+ dependencies: []
21
+
22
+ description: Adds exception notification with Radiant-managed error pages
23
+ email:
24
+ - josh@vitamin-j.com
25
+ executables: []
26
+
27
+ extensions: []
28
+
29
+ extra_rdoc_files: []
30
+
31
+ files:
32
+ - README
33
+ - Rakefile
34
+ - app/models/exception_notifier.rb
35
+ - app/models/internal_server_error_page.rb
36
+ - app/views/exception_notifier/notification.html.erb
37
+ - exception_notification_extension.rb
38
+ - lib/exception_notification.rb
39
+ - lib/exception_notification/page_extensions.rb
40
+ - lib/radiant-exception_notification-extension.rb
41
+ - lib/tasks/exception_notification_extension_tasks.rake
42
+ - radiant-exception_notification-extension.gemspec
43
+ - test/functional/exception_notification_test.rb
44
+ - test/test_helper.rb
45
+ - test/unit/exception_notifier_page_test.rb
46
+ - test/unit/exception_notifier_test.rb
47
+ has_rdoc: true
48
+ homepage: http://github.com/digitalpulp
49
+ licenses: []
50
+
51
+ post_install_message: "\n Add this to your radiant project with:\n config.gem 'radiant-exception-notification', :version => '0.8.1'\n "
52
+ rdoc_options: []
53
+
54
+ require_paths:
55
+ - lib
56
+ required_ruby_version: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ hash: 3
62
+ segments:
63
+ - 0
64
+ version: "0"
65
+ required_rubygems_version: !ruby/object:Gem::Requirement
66
+ none: false
67
+ requirements:
68
+ - - ">="
69
+ - !ruby/object:Gem::Version
70
+ hash: 3
71
+ segments:
72
+ - 0
73
+ version: "0"
74
+ requirements: []
75
+
76
+ rubyforge_project:
77
+ rubygems_version: 1.4.2
78
+ signing_key:
79
+ specification_version: 3
80
+ summary: Exception notification extension for Radiant CMS
81
+ test_files:
82
+ - test/functional/exception_notification_test.rb
83
+ - test/test_helper.rb
84
+ - test/unit/exception_notifier_page_test.rb
85
+ - test/unit/exception_notifier_test.rb