在我的一个Rails应用程序控制器中,我做了类似这样的事情:
def create
@user = User.create(user_params)
# send welcome email
UserMailer.welcome(@user).deliver_later
end
现在,我故意禁用我的Redis服务器,以便我可以复制在我的应用无法建立连接的情况下会发生的情况。
不幸的是,如果create
无法连接到Redis,则整个deliver_later
请求失败并显示500。
我想要的是请求仍然成功,但是邮件程序无声地失败。
我该如何做到这一点?
其他信息:
在config / initializers / action_mailer.rb中:
rescue_from(Redis::CannotConnectError) do |exception|
Rails.logger.error "Original record not found: #{@serialized_arguments.join(', ')}"
end
在异常时永远不会被调用。我尝试了rescue_from(StandardError)
和(Exception)
,但从未调用过。
我使用sidekiq作为我的作业队列适配器:
config.active_job.queue_adapter = :sidekiq
我得到的500错误是:
Redis::CannotConnectError (Error connecting to Redis on localhost:6379 (Errno::ECONNREFUSED)):
我的UserMailer
是ApplicationMailer
的子类,是ActionMailer::Base
的子类。
答案 0 :(得分:0)
为了防止在Redis关闭时调用deliver_later
崩溃,我们添加了以下monkey-patch:
# If +raise_delivery_errors+ is false, errors occurring while attempting to
# enqueue the email for delivery will be ignored (for instance, if Redis is
# unreachable). In these cases, the email will never be delivered.
module MessageDeliveryWithSilentQueueingErrors
def deliver_later
super
rescue Redis::CannotConnectError => e
raise if raise_delivery_errors
# Log details of the failed email here
end
def deliver_later!
super
rescue Redis::CannotConnectError => e
raise if raise_delivery_errors
# Log details of the failed email here
end
end
ActionMailer::MessageDelivery.send(:prepend, MessageDeliveryWithSilentQueueingErrors)