2

How should I wrap a deliver_now method call so we can catch errors if they occur while delivering?

@user = User.new(user_params)
if @user.valid?
  MyMailer.user_email(@user).deliver
  # hmmm....  how do we catch if the email is not sent?  
else
  ...
end
csi
  • 9,018
  • 8
  • 61
  • 81

1 Answers1

2

Make sure you have config.action_mailer.raise_delivery_errors = true set in your application config. Then you can catch exceptions with a rescue block. Something like this:

@user = User.new(user_params)
if @user.valid?
  begin
    MyMailer.user_email(@user).deliver
  rescue StandardError => e
    # do something with the messages in exception object e
    flash[:error] = 'Problems sending email'
  end
else
  ...
end
Sean Huber
  • 3,945
  • 2
  • 26
  • 31
  • I'm in a situation with a very large app that has lots of legacy code that uses the mailer and does not expect it to raise exceptions so I can't turn action_mailer.raise_delivery_errors = true on in the config. Is there a way to raise exceptions for just this delivery. Does deliver_now! accomplish this? – Brian C Apr 28 '21 at 19:23
  • I was looking at the source for deliver_now! at https://api.rubyonrails.org/classes/ActionMailer/MessageDelivery.html#method-i-deliver_now-21 `def deliver_now! processed_mailer.handle_exceptions do message.deliver! end end` It's still wrapped in handle_exceptions the only difference seems to be calling `message.deliver!` vs without the bang. Not sure if this is enough for an exception to be raised? – Brian C Apr 28 '21 at 19:26
  • @BrianC - If you're worried about unintended consequences of legacy code, one approach could be: 1) Set `raise_delivery_errors = true`. 2) In your mailer, add something like `rescue_from StandardError, with: :handle_mailer_error`. 3) Implement `handle_mailer_error` so that it conditionally re-raises them if they're the ones you are interested in, otherwise simply log them and everything works as it always did. Also ask yourself why you want to raise exceptions for only one particular email. If you're debugging delivery problems, maybe you just need to change the log level and read the logs. – Sean Huber May 05 '21 at 16:07