From 2e3681875f53008f22ecb3725b1438ec93d116ff Mon Sep 17 00:00:00 2001 From: Sebastian Martinez Date: Sun, 23 Oct 2011 19:24:22 -0200 Subject: [PATCH] Add :ignore_crawlers options. --- README.md | 28 ++++++++++++++++--- lib/exception_notifier.rb | 20 ++++++++++++- lib/exception_notifier/notifier.rb | 2 +- .../test/functional/posts_controller_test.rb | 22 +++++++++------ test/exception_notification_test.rb | 4 +++ 5 files changed, 61 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 53d17c8b..3c20d914 100644 --- a/README.md +++ b/README.md @@ -32,6 +32,9 @@ run on production. You can make it work by Customization --- + +### Sections + By default, the notification email includes four parts: request, session, environment, and backtrace (in that order). You can customize how each of those sections are rendered by placing a partial named for that part in your @@ -48,7 +51,7 @@ access to the following variables: You can reorder the sections, or exclude sections completely, by altering the ExceptionNotifier.sections variable. You can even add new sections that describe application-specific data--just add the section's name to the list -(wherever you'd like), and define the corresponding partial. +(wherever you'd like), and define the corresponding partial. #Example with two new added sections Whatever::Application.config.middleware.use ExceptionNotifier, @@ -76,14 +79,13 @@ it is made available to the email using the exception_data macro: In the above case, @document and @person would be made available to the email renderer, allowing your new section(s) to access and display them. See the existing sections defined by the plugin for examples of how to write your own. -You can also choose to exclude the exception message from the subject, which is included by default. -Use _:verbose_subject => false_ to exclude it. + +### Ignore Exceptions You can also ignore types of exceptions, which will make ExceptionNotifier avoid sending notifications for the specified exception types. To achieve that, you should use the _:ignore_exceptions_ option, like this: - #Example ignoring some exceptions Whatever::Application.config.middleware.use ExceptionNotifier, :email_prefix => "[Whatever] ", :sender_address => %{"notifier" }, @@ -96,6 +98,24 @@ By default, ExceptionNotifier ignores _ActiveRecord::RecordNotFound_, _AbstractController::ActionNotFound_ and _ActionController::RountingError_. +### Verbose + +You can also choose to exclude the exception message from the subject, which is included by default. +Use _:verbose_subject => false_ to exclude it. + +### Ignore Crawlers + +In some cases you may want to avoid getting notifications from exceptions +made by crawlers. Using _:ignore_crawlers_ options like this, + + Whatever::Application.config.middleware.use ExceptionNotifier, + :email_prefix => "[Whatever] ", + :sender_address => %{"notifier" }, + :exception_recipients => %w{exceptions@example.com}, + :ignore_crawlers => %w{Googlebot bingbot} + +will prevent sending those unwanted notifications. + Background Notifications --- diff --git a/lib/exception_notifier.rb b/lib/exception_notifier.rb index 458b4358..a7d8099d 100644 --- a/lib/exception_notifier.rb +++ b/lib/exception_notifier.rb @@ -10,6 +10,10 @@ def self.default_ignore_exceptions end end + def self.default_ignore_crawlers + [] + end + def initialize(app, options = {}) @app, @options = app, options @@ -20,6 +24,7 @@ def initialize(app, options = {}) Notifier.default_verbose_subject = @options[:verbose_subject] @options[:ignore_exceptions] ||= self.class.default_ignore_exceptions + @options[:ignore_crawlers] ||= self.class.default_ignore_crawlers end def call(env) @@ -28,11 +33,24 @@ def call(env) options = (env['exception_notifier.options'] ||= Notifier.default_options) options.reverse_merge!(@options) - unless Array.wrap(options[:ignore_exceptions]).include?(exception.class) + unless ignored_exception(options[:ignore_exceptions], exception) || from_crawler(options[:ignore_crawlers], env['HTTP_USER_AGENT']) Notifier.exception_notification(env, exception).deliver env['exception_notifier.delivered'] = true end raise exception end + + private + + def ignored_exception(ignore_array, exception) + Array.wrap(ignore_array).include?(exception.class) + end + + def from_crawler(ignore_array, agent) + ignore_array.each do |crawler| + return true if (agent =~ Regexp.new(crawler)) + end unless ignore_array.blank? + false + end end diff --git a/lib/exception_notifier/notifier.rb b/lib/exception_notifier/notifier.rb index 8766a1bc..90dffab9 100644 --- a/lib/exception_notifier/notifier.rb +++ b/lib/exception_notifier/notifier.rb @@ -31,7 +31,7 @@ def default_email_prefix def default_sections @default_sections || %w(request session environment backtrace) end - + def default_verbose_subject @default_verbose_subject.nil? || @default_verbose_subject end diff --git a/test/dummy/test/functional/posts_controller_test.rb b/test/dummy/test/functional/posts_controller_test.rb index 98f424b1..25d0d9b2 100644 --- a/test/dummy/test/functional/posts_controller_test.rb +++ b/test/dummy/test/functional/posts_controller_test.rb @@ -70,20 +70,24 @@ class PostsControllerTest < ActionController::TestCase assert @secured_mail.body.include? "* session id: [FILTERED]\n *" end - test "should not include exception message in subject" do + test "should ignore exception if from unwanted cralwer" do + request.env['HTTP_USER_AGENT'] = "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" begin @post = posts(:one) post :create, :post => @post.attributes rescue => e @exception = e custom_env = request.env - custom_env['exception_notifier.options']||={} - custom_env['exception_notifier.options'].merge!(:verbose_subject => false) - @mail = ExceptionNotifier::Notifier.exception_notification(custom_env, @exception) + custom_env['exception_notifier.options'] ||= {} + custom_env['exception_notifier.options'].merge!(:ignore_crawlers => %w(Googlebot)) + ignore_array = custom_env['exception_notifier.options'][:ignore_crawlers] + unless ExceptionNotifier.new(Dummy::Application, custom_env['exception_notifier.options']).send(:from_crawler, ignore_array, custom_env['HTTP_USER_AGENT']) + @ignored_mail = ExceptionNotifier::Notifier.exception_notification(custom_env, @exception) + end end - assert_equal "[Dummy ERROR] # (NoMethodError)", @mail.subject + + assert_nil @ignored_mail end - end class PostsControllerTestWithoutVerboseSubject < ActionController::TestCase @@ -98,8 +102,8 @@ class PostsControllerTestWithoutVerboseSubject < ActionController::TestCase @mail = ExceptionNotifier::Notifier.exception_notification(request.env, @exception) end end - + test "should not include exception message in subject" do - assert_equal "[Dummy ERROR] # (NoMethodError)", @mail.subject + assert_equal "[ERROR] # (NoMethodError)", @mail.subject end -end \ No newline at end of file +end diff --git a/test/exception_notification_test.rb b/test/exception_notification_test.rb index 5c5b1eb9..595c23c3 100644 --- a/test/exception_notification_test.rb +++ b/test/exception_notification_test.rb @@ -20,4 +20,8 @@ class ExceptionNotificationTest < ActiveSupport::TestCase test "should have verbose subject by default" do assert ExceptionNotifier::Notifier.default_options[:verbose_subject] == true end + + test "should have ignored crawler by default" do + assert ExceptionNotifier.default_ignore_crawlers == [] + end end