exception_notification 2.5.0 → 2.5.1

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.
data/README.md ADDED
@@ -0,0 +1,130 @@
1
+ Exception Notifier Plugin for Rails
2
+ ====
3
+
4
+ The Exception Notifier plugin provides a mailer object and a default set of
5
+ templates for sending email notifications when errors occur in a Rails
6
+ application. The plugin is configurable, allowing programmers to specify:
7
+
8
+ * the sender address of the email
9
+ * the recipient addresses
10
+ * the text used to prefix the subject line
11
+
12
+ The email includes information about the current request, session, and
13
+ environment, and also gives a backtrace of the exception.
14
+
15
+ Installation
16
+ ---
17
+
18
+ You can use the latest ExceptionNotification gem with Rails 3, by adding
19
+ the following line in your Gemfile
20
+
21
+ gem 'exception_notification'
22
+
23
+ As of Rails 3 ExceptionNotification is used as a rack middleware, so you can
24
+ configure its options on your config.ru file, or in the environment you
25
+ want it to run. In most cases you would want ExceptionNotification to
26
+ run on production. You can make it work by
27
+
28
+ Whatever::Application.config.middleware.use ExceptionNotifier,
29
+ :email_prefix => "[Whatever] ",
30
+ :sender_address => %{"notifier" <notifier@example.com>},
31
+ :exception_recipients => %w{exceptions@example.com}
32
+
33
+ Customization
34
+ ---
35
+
36
+ By default, the notification email includes four parts: request, session,
37
+ environment, and backtrace (in that order). You can customize how each of those
38
+ sections are rendered by placing a partial named for that part in your
39
+ app/views/exception_notifier directory (e.g., _session.rhtml). Each partial has
40
+ access to the following variables:
41
+
42
+ @controller # the controller that caused the error
43
+ @request # the current request object
44
+ @exception # the exception that was raised
45
+ @backtrace # a sanitized version of the exception's backtrace
46
+ @data # a hash of optional data values that were passed to the notifier
47
+ @sections # the array of sections to include in the email
48
+
49
+ You can reorder the sections, or exclude sections completely, by altering the
50
+ ExceptionNotifier.sections variable. You can even add new sections that
51
+ describe application-specific data--just add the section's name to the list
52
+ (wherever you'd like), and define the corresponding partial.
53
+
54
+ #Example with two new added sections
55
+ Whatever::Application.config.middleware.use ExceptionNotifier,
56
+ :email_prefix => "[Whatever] ",
57
+ :sender_address => %{"notifier" <notifier@example.com>},
58
+ :exception_recipients => %w{exceptions@example.com},
59
+ :sections => %w{my_section1 my_section2} + ExceptionNotifier::Notifier.default_sections
60
+
61
+ If your new section requires information that isn't available by default, make sure
62
+ it is made available to the email using the exception_data macro:
63
+
64
+ class ApplicationController < ActionController::Base
65
+ before_filter :log_additional_data
66
+ ...
67
+ protected
68
+ def log_additional_data
69
+ request.env["exception_notifier.exception_data"] = {
70
+ :document => @document,
71
+ :person => @person
72
+ }
73
+ end
74
+ ...
75
+ end
76
+
77
+ In the above case, @document and @person would be made available to the email
78
+ renderer, allowing your new section(s) to access and display them. See the
79
+ existing sections defined by the plugin for examples of how to write your own.
80
+
81
+ Background Notifications
82
+ ---
83
+
84
+ If you want to send notifications from a background process like
85
+ DelayedJob, you should use the background_exception_notification method
86
+ like this:
87
+
88
+ begin
89
+ some code...
90
+ rescue => e
91
+ ExceptionNotifier::Notifier.background_exception_notification(e)
92
+ end
93
+
94
+ Manually notify of exception
95
+ ---
96
+
97
+ If your controller action manually handles an error, the notifier will never be
98
+ run. To manually notify of an error you can do something like the following:
99
+
100
+ rescue_from Exception, :with => :server_error
101
+
102
+ def server_error(exception)
103
+ # Whatever code that handles the exception
104
+
105
+ ExceptionNotifier::Notifier.exception_notification(request.env, exception).deliver
106
+ end
107
+
108
+ Notification
109
+ ---
110
+
111
+ After an exception notification has been delivered the rack environment variable
112
+ 'exception_notifier.delivered' will be set to +true+.
113
+
114
+ Rails 2.3 stable and earlier
115
+ ---
116
+
117
+ If you are running Rails 2.3 then see the branch for that:
118
+
119
+ <a href="http://github.com/smartinez87/exception_notification/tree/2-3-stable">http://github.com/smartinez87/exception_notification/tree/2-3-stable</a>
120
+
121
+ If you are running pre-rack Rails then see this tag:
122
+
123
+ <a href="http://github.com/smartinez87/exception_notification/tree/pre-2-3">http://github.com/smartinez87/exception_notification/tree/pre-2-3</a>
124
+
125
+ Support and tickets
126
+ ---
127
+
128
+ <a href="https://github.com/smartinez87/exception_notification/issues">https://github.com/smartinez87/exception_notification/issues</a>
129
+
130
+ Copyright (c) 2005 Jamis Buck, released under the MIT license
@@ -0,0 +1 @@
1
+ require 'exception_notifier'
@@ -0,0 +1,37 @@
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::RecordNotFound
8
+ exceptions << ::AbstractController::ActionNotFound if defined? ::AbstractController::ActionNotFound
9
+ exceptions << ::ActionController::RoutingError if defined? ::ActionController::RoutingError
10
+ end
11
+ end
12
+
13
+ def initialize(app, options = {})
14
+ @app, @options = app, options
15
+
16
+ Notifier.default_sender_address = @options[:sender_address]
17
+ Notifier.default_exception_recipients = @options[:exception_recipients]
18
+ Notifier.default_email_prefix = @options[:email_prefix]
19
+ Notifier.default_sections = @options[:sections]
20
+
21
+ @options[:ignore_exceptions] ||= self.class.default_ignore_exceptions
22
+ end
23
+
24
+ def call(env)
25
+ @app.call(env)
26
+ rescue Exception => exception
27
+ options = (env['exception_notifier.options'] ||= Notifier.default_options)
28
+ options.reverse_merge!(@options)
29
+
30
+ unless Array.wrap(options[:ignore_exceptions]).include?(exception.class)
31
+ Notifier.exception_notification(env, exception).deliver
32
+ env['exception_notifier.delivered'] = true
33
+ end
34
+
35
+ raise exception
36
+ end
37
+ end
@@ -0,0 +1,108 @@
1
+ require 'action_mailer'
2
+ require 'pp'
3
+
4
+ class ExceptionNotifier
5
+ class Notifier < ActionMailer::Base
6
+ self.mailer_name = 'exception_notifier'
7
+
8
+ #Append application view path to the ExceptionNotifier lookup context.
9
+ self.append_view_path Rails.root.nil? ? "app/views" : "#{Rails.root}/app/views" if defined?(Rails)
10
+ self.append_view_path "#{File.dirname(__FILE__)}/views"
11
+
12
+ class << self
13
+ attr_writer :default_sender_address
14
+ attr_writer :default_exception_recipients
15
+ attr_writer :default_email_prefix
16
+ attr_writer :default_sections
17
+
18
+ def default_sender_address
19
+ @default_sender_address || %("Exception Notifier" <exception.notifier@default.com>)
20
+ end
21
+
22
+ def default_exception_recipients
23
+ @default_exception_recipients || []
24
+ end
25
+
26
+ def default_email_prefix
27
+ @default_email_prefix || "[ERROR] "
28
+ end
29
+
30
+ def default_sections
31
+ @default_sections || %w(request session environment backtrace)
32
+ end
33
+
34
+ def default_options
35
+ { :sender_address => default_sender_address,
36
+ :exception_recipients => default_exception_recipients,
37
+ :email_prefix => default_email_prefix,
38
+ :sections => default_sections }
39
+ end
40
+ end
41
+
42
+ class MissingController
43
+ def method_missing(*args, &block)
44
+ end
45
+ end
46
+
47
+ def exception_notification(env, exception)
48
+ @env = env
49
+ @exception = exception
50
+ @options = (env['exception_notifier.options'] || {}).reverse_merge(self.class.default_options)
51
+ @kontroller = env['action_controller.instance'] || MissingController.new
52
+ @request = ActionDispatch::Request.new(env)
53
+ @backtrace = clean_backtrace(exception)
54
+ @sections = @options[:sections]
55
+ data = env['exception_notifier.exception_data'] || {}
56
+
57
+ data.each do |name, value|
58
+ instance_variable_set("@#{name}", value)
59
+ end
60
+
61
+ prefix = "#{@options[:email_prefix]}#{@kontroller.controller_name}##{@kontroller.action_name}"
62
+ subject = "#{prefix} (#{@exception.class}) #{@exception.message.inspect}"
63
+ subject = subject.length > 120 ? subject[0...120] + "..." : subject
64
+
65
+ mail(:to => @options[:exception_recipients], :from => @options[:sender_address], :subject => subject) do |format|
66
+ format.text { render "#{mailer_name}/exception_notification" }
67
+ end
68
+ end
69
+
70
+ def background_exception_notification(exception)
71
+ if @notifier = Rails.application.config.middleware.detect{ |x| x.klass == ExceptionNotifier }
72
+ @options = (@notifier.args.first || {}).reverse_merge(self.class.default_options)
73
+ subject = "#{@options[:email_prefix]} (#{exception.class}) #{exception.message.inspect}"
74
+
75
+ @exception = exception
76
+ @backtrace = exception.backtrace || []
77
+ @sections = %w{backtrace}
78
+
79
+ mail(:to => @options[:exception_recipients], :from => @options[:sender_address], :subject => subject) do |format|
80
+ format.text { render "#{mailer_name}/background_exception_notification" }
81
+ end.deliver
82
+ end
83
+ end
84
+
85
+ private
86
+
87
+ def clean_backtrace(exception)
88
+ if Rails.respond_to?(:backtrace_cleaner)
89
+ Rails.backtrace_cleaner.send(:filter, exception.backtrace)
90
+ else
91
+ exception.backtrace
92
+ end
93
+ end
94
+
95
+ helper_method :inspect_object
96
+
97
+ def inspect_object(object)
98
+ case object
99
+ when Hash, Array
100
+ object.inspect
101
+ when ActionController::Base
102
+ "#{object.controller_name}##{object.action_name}"
103
+ else
104
+ object.to_s
105
+ end
106
+ end
107
+ end
108
+ 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: <%= @request.ssl? ? "[FILTERED]" : (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 background:
2
+
3
+ <%= @exception.message %>
4
+ <%= @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 %>
@@ -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 CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: exception_notification
3
3
  version: !ruby/object:Gem::Version
4
- hash: 27
4
+ hash: 25
5
5
  prerelease:
6
6
  segments:
7
7
  - 2
8
8
  - 5
9
- - 0
10
- version: 2.5.0
9
+ - 1
10
+ version: 2.5.1
11
11
  platform: ruby
12
12
  authors:
13
13
  - Jamis Buck
@@ -16,8 +16,7 @@ autorequire:
16
16
  bindir: bin
17
17
  cert_chain: []
18
18
 
19
- date: 2011-08-27 00:00:00 -03:00
20
- default_executable:
19
+ date: 2011-08-29 00:00:00 Z
21
20
  dependencies:
22
21
  - !ruby/object:Gem::Dependency
23
22
  name: actionmailer
@@ -76,12 +75,22 @@ extensions: []
76
75
  extra_rdoc_files: []
77
76
 
78
77
  files:
78
+ - lib/exception_notification.rb
79
+ - lib/exception_notifier.rb
80
+ - lib/exception_notifier/notifier.rb
81
+ - lib/exception_notifier/views/exception_notifier/_backtrace.text.erb
82
+ - lib/exception_notifier/views/exception_notifier/_environment.text.erb
83
+ - lib/exception_notifier/views/exception_notifier/_request.text.erb
84
+ - lib/exception_notifier/views/exception_notifier/_session.text.erb
85
+ - lib/exception_notifier/views/exception_notifier/_title.text.erb
86
+ - lib/exception_notifier/views/exception_notifier/background_exception_notification.text.erb
87
+ - lib/exception_notifier/views/exception_notifier/exception_notification.text.erb
79
88
  - Rakefile
80
89
  - .gemtest
81
- - test/exception_notification_test.rb
82
- - test/dummy/test/functional/posts_controller_test.rb
90
+ - README.md
83
91
  - test/background_exception_notification_test.rb
84
- has_rdoc: true
92
+ - test/dummy/test/functional/posts_controller_test.rb
93
+ - test/exception_notification_test.rb
85
94
  homepage:
86
95
  licenses: []
87
96
 
@@ -111,11 +120,11 @@ required_rubygems_version: !ruby/object:Gem::Requirement
111
120
  requirements: []
112
121
 
113
122
  rubyforge_project:
114
- rubygems_version: 1.5.0
123
+ rubygems_version: 1.7.1
115
124
  signing_key:
116
125
  specification_version: 3
117
126
  summary: Exception notification by email for Rails apps
118
127
  test_files:
119
- - test/exception_notification_test.rb
120
- - test/dummy/test/functional/posts_controller_test.rb
121
128
  - test/background_exception_notification_test.rb
129
+ - test/dummy/test/functional/posts_controller_test.rb
130
+ - test/exception_notification_test.rb