diff options
author | Jeremy Daer <jeremydaer@gmail.com> | 2016-05-13 17:43:48 -0700 |
---|---|---|
committer | Jeremy Daer <jeremydaer@gmail.com> | 2016-05-15 18:44:16 -0700 |
commit | e35b98e6f5c54330245645f2ed40d56c74538902 (patch) | |
tree | 272bba30020bde27d177d2cf6227dfa8bb7a525f /actionmailer/lib/action_mailer/delivery_job.rb | |
parent | 6810847f495cd282c2659be738ac8271ecdec12f (diff) | |
download | rails-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.rb | 21 |
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 |