问题
The problem is how can I catch exception in delivering mail by ActionMailer. For me it sounds impossible, because in this case ActionMailer should sent mail to mailserver, and if mailserver returns error, ActionMailer should show me this error. I am interested only in counting undelivered mails.
Do you have any ideas how to implement this? Thanks!
回答1:
I'm using something like this in the controller:
if @user.save
begin
UserMailer.welcome_email(@user).deliver
flash[:success] = "#{@user.name} created"
rescue Net::SMTPAuthenticationError, Net::SMTPServerBusy, Net::SMTPSyntaxError, Net::SMTPFatalError, Net::SMTPUnknownError => e
flash[:success] = "Utente #{@user.name} creato. Problems sending mail"
end
redirect_to "/"
回答2:
This should work in any of your environment files. development.rb
or production.rb
config.action_mailer.raise_delivery_errors = true
回答3:
If you are sending a lot of emails, you can also keep your code more DRY and get notifications of exceptions to your email by doing something like this:
status = Utility.try_delivering_email do
ClientMailer.signup_confirmation(@client).deliver
end
unless status
flash.now[:error] = "Something went wrong when we tried sending you and email :("
end
Utility Class:
class Utility
# Logs and emails exception
# Optional args:
# request: request Used for the ExceptionNotifier
# info: "A descriptive messsage"
def self.log_exception(e, args = {})
extra_info = args[:info]
Rails.logger.error extra_info if extra_info
Rails.logger.error e.message
st = e.backtrace.join("\n")
Rails.logger.error st
extra_info ||= "<NO DETAILS>"
request = args[:request]
env = request ? request.env : {}
ExceptionNotifier::Notifier.exception_notification(env, e, :data => {:message => "Exception: #{extra_info}"}).deliver
end
def self.try_delivering_email(options = {}, &block)
begin
yield
return true
rescue EOFError,
IOError,
TimeoutError,
Errno::ECONNRESET,
Errno::ECONNABORTED,
Errno::EPIPE,
Errno::ETIMEDOUT,
Net::SMTPAuthenticationError,
Net::SMTPServerBusy,
Net::SMTPSyntaxError,
Net::SMTPUnknownError,
OpenSSL::SSL::SSLError => e
log_exception(e, options)
return false
end
end
end
Got my original inspiration from here: http://www.railsonmaui.com/blog/2013/05/08/strategies-for-rails-logging-and-error-handling/
回答4:
class ApplicationMailer < ActionMailer::Base
rescue_from [ExceptionThatShouldBeRescued] do |exception|
#handle it here
end
end
Works with rails 5 onwards. And it's the best practice.
来源:https://stackoverflow.com/questions/8709984/how-to-catch-error-exception-in-actionmailer