aboutsummaryrefslogtreecommitdiffstats
path: root/actionmailer/lib/action_mailer/delivery_job.rb
diff options
context:
space:
mode:
authorJeremy Daer <jeremydaer@gmail.com>2016-05-13 17:43:48 -0700
committerJeremy Daer <jeremydaer@gmail.com>2016-05-15 18:44:16 -0700
commite35b98e6f5c54330245645f2ed40d56c74538902 (patch)
tree272bba30020bde27d177d2cf6227dfa8bb7a525f /actionmailer/lib/action_mailer/delivery_job.rb
parent6810847f495cd282c2659be738ac8271ecdec12f (diff)
downloadrails-e35b98e6f5c54330245645f2ed40d56c74538902.tar.gz
rails-e35b98e6f5c54330245645f2ed40d56c74538902.tar.bz2
rails-e35b98e6f5c54330245645f2ed40d56c74538902.zip
Action Mailer: Declarative exception handling with `rescue_from`.
Follows the same pattern as controllers and jobs. Exceptions raised in delivery jobs (enqueued by `#deliver_later`) are also delegated to the mailer's rescue_from handlers, so you can handle the DeserializationError raised by delivery jobs: ```ruby class MyMailer < ApplicationMailer rescue_from ActiveJob::DeserializationError do … end ``` ActiveSupport::Rescuable polish: * Add the `rescue_with_handler` class method so exceptions may be handled at the class level without requiring an instance. * Rationalize `exception.cause` handling. If no handler matches the exception, fall back to the handler that matches its cause. * Handle exceptions raised elsewhere. Pass `object: …` to execute the `rescue_from` handler (e.g. a method call or a block to instance_exec) against a different object. Defaults to `self`.
Diffstat (limited to 'actionmailer/lib/action_mailer/delivery_job.rb')
-rw-r--r--actionmailer/lib/action_mailer/delivery_job.rb21
1 files changed, 21 insertions, 0 deletions
diff --git a/actionmailer/lib/action_mailer/delivery_job.rb b/actionmailer/lib/action_mailer/delivery_job.rb
index 52772af2d3..d371c1b61a 100644
--- a/actionmailer/lib/action_mailer/delivery_job.rb
+++ b/actionmailer/lib/action_mailer/delivery_job.rb
@@ -3,11 +3,32 @@ require 'active_job'
module ActionMailer
# The <tt>ActionMailer::DeliveryJob</tt> class is used when you
# want to send emails outside of the request-response cycle.
+ #
+ # Exceptions are rescued and handled by the mailer class.
class DeliveryJob < ActiveJob::Base # :nodoc:
queue_as { ActionMailer::Base.deliver_later_queue_name }
+ rescue_from StandardError, with: :handle_exception_with_mailer_class
+
def perform(mailer, mail_method, delivery_method, *args) #:nodoc:
mailer.constantize.public_send(mail_method, *args).send(delivery_method)
end
+
+ private
+ # "Deserialize" the mailer class name by hand in case another argument
+ # (like a Global ID reference) raised DeserializationError.
+ def mailer_class
+ if mailer = Array(@serialized_arguments).first || Array(arguments).first
+ mailer.constantize
+ end
+ end
+
+ def handle_exception_with_mailer_class(exception)
+ if klass = mailer_class
+ klass.handle_exception exception
+ else
+ raise exception
+ end
+ end
end
end