From f7a986012a6099445e20b6414d253ee0fc039118 Mon Sep 17 00:00:00 2001 From: eileencodes Date: Wed, 27 Apr 2016 15:47:22 -0500 Subject: Prep Rails 5 beta 4 --- actionmailer/lib/action_mailer/gem_version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'actionmailer/lib') diff --git a/actionmailer/lib/action_mailer/gem_version.rb b/actionmailer/lib/action_mailer/gem_version.rb index cbe5fc3e64..d8e3a6ddbe 100644 --- a/actionmailer/lib/action_mailer/gem_version.rb +++ b/actionmailer/lib/action_mailer/gem_version.rb @@ -8,7 +8,7 @@ module ActionMailer MAJOR = 5 MINOR = 0 TINY = 0 - PRE = "beta3" + PRE = "beta4" STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".") end -- cgit v1.2.3 From fbdcf5221ad7ea3d40ad09651962fc85d101dd67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Mendon=C3=A7a=20Fran=C3=A7a?= Date: Fri, 6 May 2016 16:54:40 -0500 Subject: Preparing for 5.0.0.rc1 release --- actionmailer/lib/action_mailer/gem_version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'actionmailer/lib') diff --git a/actionmailer/lib/action_mailer/gem_version.rb b/actionmailer/lib/action_mailer/gem_version.rb index d8e3a6ddbe..759b932c58 100644 --- a/actionmailer/lib/action_mailer/gem_version.rb +++ b/actionmailer/lib/action_mailer/gem_version.rb @@ -8,7 +8,7 @@ module ActionMailer MAJOR = 5 MINOR = 0 TINY = 0 - PRE = "beta4" + PRE = "rc1" STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".") end -- cgit v1.2.3 From 7cffd6b372369e93ef74c01229a0507d4086e169 Mon Sep 17 00:00:00 2001 From: Pedro Adame Vergara Date: Mon, 9 May 2016 20:37:18 +0200 Subject: Add :ssl/:tls to ActionMailer [ci skip] --- actionmailer/lib/action_mailer/base.rb | 1 + 1 file changed, 1 insertion(+) (limited to 'actionmailer/lib') diff --git a/actionmailer/lib/action_mailer/base.rb b/actionmailer/lib/action_mailer/base.rb index 4bb7842297..10ee5490c3 100644 --- a/actionmailer/lib/action_mailer/base.rb +++ b/actionmailer/lib/action_mailer/base.rb @@ -392,6 +392,7 @@ module ActionMailer # of an OpenSSL verify constant ('none', 'peer', 'client_once', # 'fail_if_no_peer_cert') or directly the constant (OpenSSL::SSL::VERIFY_NONE, # OpenSSL::SSL::VERIFY_PEER, ...). + # :ssl/:tls Enables the SMTP connection to use SMTP/TLS (SMTPS: SMTP over direct TLS connection) # # * sendmail_settings - Allows you to override options for the :sendmail delivery method. # * :location - The location of the sendmail executable. Defaults to /usr/sbin/sendmail. -- cgit v1.2.3 From 8ecc5ab1d88532a239f17c7520ed922c7579b01c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Mendon=C3=A7a=20Fran=C3=A7a?= Date: Tue, 10 May 2016 01:07:09 -0300 Subject: Start Rails 5.1 development :tada: --- actionmailer/lib/action_mailer/gem_version.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'actionmailer/lib') diff --git a/actionmailer/lib/action_mailer/gem_version.rb b/actionmailer/lib/action_mailer/gem_version.rb index 759b932c58..7dafceef2b 100644 --- a/actionmailer/lib/action_mailer/gem_version.rb +++ b/actionmailer/lib/action_mailer/gem_version.rb @@ -6,9 +6,9 @@ module ActionMailer module VERSION MAJOR = 5 - MINOR = 0 + MINOR = 1 TINY = 0 - PRE = "rc1" + PRE = "alpha" STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".") end -- cgit v1.2.3 From e35b98e6f5c54330245645f2ed40d56c74538902 Mon Sep 17 00:00:00 2001 From: Jeremy Daer Date: Fri, 13 May 2016 17:43:48 -0700 Subject: Action Mailer: Declarative exception handling with `rescue_from`. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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`. --- actionmailer/lib/action_mailer/base.rb | 2 + actionmailer/lib/action_mailer/delivery_job.rb | 21 ++++++++ actionmailer/lib/action_mailer/message_delivery.rb | 59 ++++++++++++++-------- actionmailer/lib/action_mailer/rescuable.rb | 27 ++++++++++ 4 files changed, 87 insertions(+), 22 deletions(-) create mode 100644 actionmailer/lib/action_mailer/rescuable.rb (limited to 'actionmailer/lib') diff --git a/actionmailer/lib/action_mailer/base.rb b/actionmailer/lib/action_mailer/base.rb index 10ee5490c3..ea5af9e4f2 100644 --- a/actionmailer/lib/action_mailer/base.rb +++ b/actionmailer/lib/action_mailer/base.rb @@ -5,6 +5,7 @@ require 'active_support/core_ext/hash/except' require 'active_support/core_ext/module/anonymous' require 'action_mailer/log_subscriber' +require 'action_mailer/rescuable' module ActionMailer # Action Mailer allows you to send email from your application using a mailer model and views. @@ -420,6 +421,7 @@ module ActionMailer # * deliver_later_queue_name - The name of the queue used with deliver_later. class Base < AbstractController::Base include DeliveryMethods + include Rescuable include Previews abstract! 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 ActionMailer::DeliveryJob 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 diff --git a/actionmailer/lib/action_mailer/message_delivery.rb b/actionmailer/lib/action_mailer/message_delivery.rb index d638057d72..c5ba5f9f1d 100644 --- a/actionmailer/lib/action_mailer/message_delivery.rb +++ b/actionmailer/lib/action_mailer/message_delivery.rb @@ -1,7 +1,6 @@ require 'delegate' module ActionMailer - # The ActionMailer::MessageDelivery class is used by # ActionMailer::Base when creating a new mailer. # MessageDelivery is a wrapper (+Delegator+ subclass) around a lazy @@ -14,30 +13,35 @@ module ActionMailer # Notifier.welcome(User.first).deliver_later # enqueue email delivery as a job through Active Job # Notifier.welcome(User.first).message # a Mail::Message object class MessageDelivery < Delegator - def initialize(mailer, mail_method, *args) #:nodoc: - @mailer = mailer - @mail_method = mail_method - @args = args - @obj = nil + def initialize(mailer_class, action, *args) #:nodoc: + @mailer_class, @action, @args = mailer_class, action, args + + # The mail is only processed if we try to call any methods on it. + # Typical usage will leave it unloaded and call deliver_later. + @processed_mailer = nil + @mail_message = nil end + # Method calls are delegated to the Mail::Message that's ready to deliver. def __getobj__ #:nodoc: - @obj ||= begin - mailer = @mailer.new - mailer.process @mail_method, *@args - mailer.message - end + @mail_message ||= processed_mailer.message end - def __setobj__(obj) #:nodoc: - @obj = obj + # Unused except for delegator internals (dup, marshaling). + def __setobj__(mail_message) #:nodoc: + @mail_message = mail_message end - # Returns the Mail::Message object + # Returns the resulting Mail::Message def message __getobj__ end + # Was the delegate loaded, causing the mailer action to be processed? + def processed? + @processed_mailer || @mail_message + end + # Enqueues the email to be delivered through Active Job. When the # job runs it will send the email using +deliver_now!+. That means # that the message will be sent bypassing checking +perform_deliveries+ @@ -78,7 +82,9 @@ module ActionMailer # Notifier.welcome(User.first).deliver_now! # def deliver_now! - message.deliver! + processed_mailer.handle_exceptions do + message.deliver! + end end # Delivers an email: @@ -86,24 +92,33 @@ module ActionMailer # Notifier.welcome(User.first).deliver_now # def deliver_now - message.deliver + processed_mailer.handle_exceptions do + message.deliver + end end private + # Returns the processed Mailer instance. We keep this instance + # on hand so we can delegate exception handling to it. + def processed_mailer + @processed_mailer ||= @mailer_class.new.tap do |mailer| + mailer.process @action, *@args + end + end def enqueue_delivery(delivery_method, options={}) - if @obj - raise "You've accessed the message before asking to deliver it " \ - "later, so you may have made local changes that would be " \ - "silently lost if we enqueued a job to deliver it. Why? Only " \ + if processed? + ::Kernel.raise "You've accessed the message before asking to " \ + "deliver it later, so you may have made local changes that would " \ + "be silently lost if we enqueued a job to deliver it. Why? Only " \ "the mailer method *arguments* are passed with the delivery job! " \ "Do not access the message in any way if you mean to deliver it " \ "later. Workarounds: 1. don't touch the message before calling " \ "#deliver_later, 2. only touch the message *within your mailer " \ "method*, or 3. use a custom Active Job instead of #deliver_later." else - args = @mailer.name, @mail_method.to_s, delivery_method.to_s, *@args - ActionMailer::DeliveryJob.set(options).perform_later(*args) + args = @mailer_class.name, @action.to_s, delivery_method.to_s, *@args + ::ActionMailer::DeliveryJob.set(options).perform_later(*args) end end end diff --git a/actionmailer/lib/action_mailer/rescuable.rb b/actionmailer/lib/action_mailer/rescuable.rb new file mode 100644 index 0000000000..f2eabfa057 --- /dev/null +++ b/actionmailer/lib/action_mailer/rescuable.rb @@ -0,0 +1,27 @@ +module ActionMailer #:nodoc: + # Provides `rescue_from` for mailers. Wraps mailer action processing, + # mail job processing, and mail delivery. + module Rescuable + extend ActiveSupport::Concern + include ActiveSupport::Rescuable + + class_methods do + def handle_exception(exception) #:nodoc: + rescue_with_handler(exception) || raise(exception) + end + end + + def handle_exceptions #:nodoc: + yield + rescue => exception + rescue_with_handler(exception) || raise + end + + private + def process(*) + handle_exceptions do + super + end + end + end +end -- cgit v1.2.3