exception_notification_rails3 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/README ADDED
@@ -0,0 +1,81 @@
1
+ = Exception Notifier Plugin for Rails
2
+
3
+ The Exception Notifier plugin provides a mailer object and a default set of
4
+ templates for sending email notifications when errors occur in a Rails
5
+ application. The plugin is configurable, allowing programmers to specify:
6
+
7
+ * the sender address of the email
8
+ * the recipient addresses
9
+ * the text used to prefix the subject line
10
+
11
+ The email includes information about the current request, session, and
12
+ environment, and also gives a backtrace of the exception.
13
+
14
+ == Usage
15
+
16
+ As of Rails 3 ExceptionNotifier is used as a rack middleware
17
+
18
+ Whatever::Application.config.middleware.use ExceptionNotifier,
19
+ :email_prefix => "[Whatever] ",
20
+ :sender_address => %{"notifier" <notifier@example.com>},
21
+ :exception_recipients => %w{exceptions@example.com}
22
+
23
+ == Customization
24
+
25
+ By default, the notification email includes four parts: request, session,
26
+ environment, and backtrace (in that order). You can customize how each of those
27
+ sections are rendered by placing a partial named for that part in your
28
+ app/views/exception_notifier directory (e.g., _session.rhtml). Each partial has
29
+ access to the following variables:
30
+
31
+ * @controller: the controller that caused the error
32
+ * @request: the current request object
33
+ * @exception: the exception that was raised
34
+ * @backtrace: a sanitized version of the exception's backtrace
35
+ * @data: a hash of optional data values that were passed to the notifier
36
+ * @sections: the array of sections to include in the email
37
+
38
+ You can reorder the sections, or exclude sections completely, by altering the
39
+ ExceptionNotifier.sections variable. You can even add new sections that
40
+ describe application-specific data--just add the section's name to the list
41
+ (whereever you'd like), and define the corresponding partial. Then, if your
42
+ new section requires information that isn't available by default, make sure
43
+ it is made available to the email using the exception_data macro:
44
+
45
+ class ApplicationController < ActionController::Base
46
+ before_filter :log_additional_data
47
+ ...
48
+ protected
49
+ def log_additional_data
50
+ request.env["exception_notifier.exception_data"] = {
51
+ :document => @document,
52
+ :person => @person
53
+ }
54
+ end
55
+ ...
56
+ end
57
+
58
+ In the above case, @document and @person would be made available to the email
59
+ renderer, allowing your new section(s) to access and display them. See the
60
+ existing sections defined by the plugin for examples of how to write your own.
61
+
62
+ == Notification
63
+
64
+ After an exception notification has been delivered the rack environment variable
65
+ 'exception_notifier.delivered' will be set to +true+.
66
+
67
+ == Rails 2.3 stable and earlier
68
+
69
+ If you are running Rails 2.3 then see the branch for that:
70
+
71
+ http://github.com/rails/exception_notification/tree/2-3-stable
72
+
73
+ If you are running pre-rack Rails then see this tag:
74
+
75
+ http://github.com/rails/exception_notification/tree/pre-2-3
76
+
77
+ == Support and tickets
78
+
79
+ https://rails.lighthouseapp.com/projects/8995-rails-plugins
80
+
81
+ Copyright (c) 2005 Jamis Buck, released under the MIT license
@@ -0,0 +1,31 @@
1
+ require 'action_dispatch'
2
+ require 'exception_notifier/notifier'
3
+
4
+ class ExceptionNotifier
5
+ def self.default_ignore_exceptions
6
+ [].tap do |exceptions|
7
+ exceptions << ActiveRecord::RecordNotFound if defined? ActiveRecord
8
+ exceptions << AbstractController::ActionNotFound if defined? AbstractController
9
+ exceptions << ActionController::RoutingError if defined? ActionController
10
+ end
11
+ end
12
+
13
+ def initialize(app, options = {})
14
+ @app, @options = app, options
15
+ @options[:ignore_exceptions] ||= self.class.default_ignore_exceptions
16
+ end
17
+
18
+ def call(env)
19
+ @app.call(env)
20
+ rescue Exception => exception
21
+ options = (env['exception_notifier.options'] ||= {})
22
+ options.reverse_merge!(@options)
23
+
24
+ unless Array.wrap(options[:ignore_exceptions]).include?(exception.class)
25
+ Notifier.exception_notification(env, exception).deliver
26
+ env['exception_notifier.delivered'] = true
27
+ end
28
+
29
+ raise exception
30
+ end
31
+ end
@@ -0,0 +1,83 @@
1
+ require 'action_mailer'
2
+ require 'pp'
3
+
4
+ class ExceptionNotifier
5
+ class Notifier < ActionMailer::Base
6
+ self.mailer_name = 'exception_notifier'
7
+ self.append_view_path "#{File.dirname(__FILE__)}/views"
8
+
9
+ class << self
10
+ def default_sender_address
11
+ %("Exception Notifier" <exception.notifier@default.com>)
12
+ end
13
+
14
+ def default_exception_recipients
15
+ []
16
+ end
17
+
18
+ def default_email_prefix
19
+ "[ERROR] "
20
+ end
21
+
22
+ def default_sections
23
+ %w(request session environment backtrace)
24
+ end
25
+
26
+ def default_options
27
+ { :sender_address => default_sender_address,
28
+ :exception_recipients => default_exception_recipients,
29
+ :email_prefix => default_email_prefix,
30
+ :sections => default_sections }
31
+ end
32
+ end
33
+
34
+ class MissingController
35
+ def method_missing(*args, &block)
36
+ end
37
+ end
38
+
39
+ def exception_notification(env, exception)
40
+ @env = env
41
+ @exception = exception
42
+ @options = (env['exception_notifier.options'] || {}).reverse_merge(self.class.default_options)
43
+ @kontroller = env['action_controller.instance'] || MissingController.new
44
+ @request = ActionDispatch::Request.new(env)
45
+ @backtrace = clean_backtrace(exception)
46
+ @sections = @options[:sections]
47
+ data = env['exception_notifier.exception_data'] || {}
48
+
49
+ data.each do |name, value|
50
+ instance_variable_set("@#{name}", value)
51
+ end
52
+
53
+ prefix = "#{@options[:email_prefix]}#{@kontroller.controller_name}##{@kontroller.action_name}"
54
+ subject = "#{prefix} (#{@exception.class}) #{@exception.message.inspect}"
55
+
56
+ mail(:to => @options[:exception_recipients], :from => @options[:sender_address], :subject => subject) do |format|
57
+ format.text { render "#{mailer_name}/exception_notification" }
58
+ end
59
+ end
60
+
61
+ private
62
+
63
+ def clean_backtrace(exception)
64
+ Rails.respond_to?(:backtrace_cleaner) ?
65
+ Rails.backtrace_cleaner.send(:filter, exception.backtrace) :
66
+ exception.backtrace
67
+ end
68
+
69
+ helper_method :inspect_object
70
+
71
+ def inspect_object(object)
72
+ case object
73
+ when Hash, Array
74
+ object.inspect
75
+ when ActionController::Base
76
+ "#{object.controller_name}##{object.action_name}"
77
+ else
78
+ object.to_s
79
+ end
80
+ end
81
+
82
+ end
83
+ end
@@ -0,0 +1 @@
1
+ <%= raw @backtrace.join("\n") %>
@@ -0,0 +1,8 @@
1
+ <% filtered_env = @request.filtered_env -%>
2
+ <% max = filtered_env.keys.max { |a, b| a.length <=> b.length } -%>
3
+ <% filtered_env.keys.sort.each do |key| -%>
4
+ * <%= raw("%-*s: %s" % [max.length, key, inspect_object(filtered_env[key])]) %>
5
+ <% end -%>
6
+
7
+ * Process: <%= raw $$ %>
8
+ * Server : <%= raw `hostname -s`.chomp %>
@@ -0,0 +1,4 @@
1
+ * URL : <%= raw @request.url %>
2
+ * IP address: <%= raw @request.remote_ip %>
3
+ * Parameters: <%= raw @request.filtered_parameters.inspect %>
4
+ * Rails root: <%= raw Rails.root %>
@@ -0,0 +1,2 @@
1
+ * session id: <%= raw @request.session['session_id'].inspect.html_safe %>
2
+ * data: <%= raw PP.pp(@request.session, "") %>
@@ -0,0 +1,3 @@
1
+ -------------------------------
2
+ <%= raw title.to_s.humanize %>:
3
+ -------------------------------
@@ -0,0 +1,13 @@
1
+ A <%= @exception.class %> occurred in <%= @kontroller.controller_name %>#<%= @kontroller.action_name %>:
2
+
3
+ <%= raw @exception.message %>
4
+ <%= raw @backtrace.first %>
5
+
6
+ <% sections = @sections.map do |section|
7
+ summary = render(section).strip
8
+ unless summary.blank?
9
+ title = render("title", :title => section).strip
10
+ "#{title}\n\n#{summary.gsub(/^/, " ")}\n\n"
11
+ end
12
+ end %>
13
+ <%= raw sections.join %>
metadata ADDED
@@ -0,0 +1,76 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: exception_notification_rails3
3
+ version: !ruby/object:Gem::Version
4
+ hash: 23
5
+ prerelease: false
6
+ segments:
7
+ - 1
8
+ - 0
9
+ - 0
10
+ version: 1.0.0
11
+ platform: ruby
12
+ authors:
13
+ - Jamis Buck
14
+ - Josh Peek
15
+ autorequire:
16
+ bindir: bin
17
+ cert_chain: []
18
+
19
+ date: 2010-03-13 00:00:00 +02:00
20
+ default_executable:
21
+ dependencies: []
22
+
23
+ description:
24
+ email: timocratic@gmail.com
25
+ executables: []
26
+
27
+ extensions: []
28
+
29
+ extra_rdoc_files: []
30
+
31
+ files:
32
+ - README
33
+ - lib/exception_notifier/views/exception_notifier/_backtrace.text.erb
34
+ - lib/exception_notifier/views/exception_notifier/_environment.text.erb
35
+ - lib/exception_notifier/views/exception_notifier/exception_notification.text.erb
36
+ - lib/exception_notifier/views/exception_notifier/_session.text.erb
37
+ - lib/exception_notifier/views/exception_notifier/_request.text.erb
38
+ - lib/exception_notifier/views/exception_notifier/_title.text.erb
39
+ - lib/exception_notifier/notifier.rb
40
+ - lib/exception_notifier.rb
41
+ has_rdoc: true
42
+ homepage: http://github.com/railsware/exception_notification
43
+ licenses: []
44
+
45
+ post_install_message:
46
+ rdoc_options: []
47
+
48
+ require_paths:
49
+ - lib
50
+ required_ruby_version: !ruby/object:Gem::Requirement
51
+ none: false
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ hash: 3
56
+ segments:
57
+ - 0
58
+ version: "0"
59
+ required_rubygems_version: !ruby/object:Gem::Requirement
60
+ none: false
61
+ requirements:
62
+ - - ">="
63
+ - !ruby/object:Gem::Version
64
+ hash: 3
65
+ segments:
66
+ - 0
67
+ version: "0"
68
+ requirements: []
69
+
70
+ rubyforge_project:
71
+ rubygems_version: 1.3.7
72
+ signing_key:
73
+ specification_version: 3
74
+ summary: Exception notification by email for Rails apps
75
+ test_files: []
76
+