Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

Already on GitHub? Sign in to your account

Action Mailer 3.2.8 not raising delivery error #7473

Closed
Alamoz opened this Issue Aug 28, 2012 · 16 comments

Comments

Projects
None yet
4 participants

Alamoz commented Aug 28, 2012

In a Rails 3.2.8 app, I've configured Active Mailer to raise configuration errors, in /config/environments/production.rb:

  config.action_mailer.raise_delivery_errors = true

In the code performing notification:

  begin
    @user.deliver_activation_instructions!
  rescue  Exception => e
    logger.warn "email delivery error = #{e}"
  end

I've also tried looking at the return value:

  mailer_result =  @user.deliver_activation_instructions!
  logger.info "email result = #{mailer_result}"

Then I've purposely input an invalid email address, which results in a Postfix error in /var/log/mail.log:

  ... Recipient address rejected: User unknown in local recipient table (in reply to RCPT TO command) ...

The call to @user.deliver_activation_instructions! isn't throwing an exception, and the return value is always the email message, regardless of the fact that Postgres isn't delivering the email. It would be cool to be able to detect a failed email delivery attempt. Shouldn't the above configuration option cause that to happen?

Thanks!

Member

steveklabnik commented Aug 28, 2012

What does deliver_activiation_instructions! look like?

Alamoz commented Aug 28, 2012

Just the plain vanilla code used to deliver an activation email for Authlogic, it works fine with a valid email address, and otherwise is also fine, it just isn't throwing an exception when the email address is invalid:

def deliver_activation_instructions!
  reset_perishable_token!
  self.save
  Notifier.activation_instructions(self, self.perishable_token).deliver
end

The notifier simply informs the user to click on a registration/activation link comprised of a url and the perishable token.

Ah, is it because it needs to use "deliver!"

Alamoz commented Aug 28, 2012

Just tried:

  Notifier.activation_instructions(self, self.perishable_token).deliver!

And it still doesn't throw an error.

Member

steveklabnik commented Aug 28, 2012

(you can use triple backticks to mark a code block, I edited your post to have them.)

Thanks. Yeah, something strange is happening. This looks right to me.

Member

steveklabnik commented Aug 28, 2012

Do you have any other mailers? Do they throw things properly?

Alamoz commented Aug 28, 2012

I have other mailers, but right now I'm not checking them for errors. I'd like to just get this first one working then do the others later. I want to do this first one so I can have a cron job check for failed deliveries and try resending a few times before wiping the new user record from the database. This is the most important one.

Member

steveklabnik commented Aug 28, 2012

I'd like to just get this first one working then do the others later.

Right, but what I mean is if you check the other ones, you can see if it's across all mailers or just this specific one. That may be relevant.

Alamoz commented Aug 29, 2012

OK, I just added error trapping to the password reset email, then tried sending it to a non-existent Yahoo email account. The notifier didn't throw any error and the error in the Postfix log is:

... 554 delivery error: dd This user doesn't have a yahoo.com account ...

So a different mailer is also not raising the delivery failure error.

Contributor

al2o3cr commented Aug 30, 2012

I'm pretty sure the interaction with Postfix isn't synchronous with the actual sending - in other words, the sendmail call or SMTP session either succeeds or fails based on whether the message gets queued, not delivered.

Alamoz commented Aug 30, 2012

Yes, that is the conclusion I've come to after digging through action_mailer, mail, and Net::SMTP. I may spend some time modifying one of those, would really like to know if the mail is deliverable. Thanks.

Maybe I should close this, but perhaps someone else has some suggestions. The configuration suggests action_mailer will throw an exception if the mall can't be delivered. In Net::SMTP the code checks for 50x SMTP return values and throws an exception for them. That is what threw me off.

Alamoz commented Aug 30, 2012

DHH runs a script to tail the postfix log file and relates the data back to the rails app, see http://37signals.com/svn/posts/3096-giving-away-the-secrets-of-993-email-delivery - Something like that looks like a relatively simple solution. Guess I'll close this issue.

@Alamoz Alamoz closed this Aug 30, 2012

Owner

pixeltrix commented Aug 30, 2012

It will raise an error if the mail server you're talking to is the final destination for that email, e.g:

>> ActionMailer::Base.delivery_method
=> :smtp
>> ActionMailer::Base.smtp_settings
=> {:address=>"mail.pixeltrix.co.uk", :port=>25, :domain=>"www.pixeltrix.co.uk"}
>> Notifier.welcome('andyw2@pixeltrix.co.uk').deliver
Net::SMTPFatalError: 550 5.1.1 <andyw2@pixeltrix.co.uk>: Recipient address rejected: User unknown in virtual mailbox table

if however the server you're talking to is relaying the mail then you won't get an error as it queues the email, e.g:

>> ActionMailer::Base.delivery_method
=> :smtp
>> ActionMailer::Base.smtp_settings
=> {:address=>"mail.centralsports.co.uk", :port=>25, :domain=>"www.centralsports.co.uk"}
>> Notifier.welcome('andyw2@pixeltrix.co.uk').deliver
=> #<Mail::Message:2168996780, Multipart: false, Headers: <Return-Path: postmaster@pixeltrix.co.uk>, <Date: Thu, 30 Aug 2012 04:11:54 +0100>, <From: andyw@pixeltrix.co.uk>, <To: andyw2@pixeltrix.co.uk>, <Message-ID: <503ed9faa50fc_77068044394863624@aw-macbook-pro.local.mail>>, <Subject: Welcome>, <Mime-Version: 1.0>, <Content-Type: text/plain>, <Content-Transfer-Encoding: 7bit>>

if the mail server is setup correctly it will bounce the email to the address specified in Return-Path: so you can setup a special email account to receive those bounces and process them asynchronously by whatever DelayedJob/Resque/Sidekiq background worker system you are using.

Owner

pixeltrix commented Aug 30, 2012

Just to note if you try to use the servers above for testing you'll likely get the following:

>> Notifier.welcome('andyw@pixeltrix.co.uk').deliver
Net::SMTPFatalError: 554 5.7.1 Service unavailable; Client host [xxx.xxx.xxx.xxx] blocked using zen.spamhaus.org; http://www.spamhaus.org/query/bl?ip=xxx.xxx.xxx.xxx

where xxx.xxx.xxx.xxx is obviously the IP address of the rails application.

Alamoz commented Aug 30, 2012

Makes sense, but I have my Postfix delivering directly (i.e. "relayhost = " in main.cf).

Owner

pixeltrix commented Aug 30, 2012

Makes sense, but I have my Postfix delivering directly (i.e. "relayhost = " in main.cf)

But what is your :address in :smtp_settings? If it's localhost then your local copy of postfix is doing the queuing. The Net::SMTP instance needs to be talking to the final destination - anything else will just queue the email for processing.

Alamoz commented Aug 30, 2012

Ah, I see. Thank you.

@Alamoz Alamoz pushed a commit to Alamoz/docrails that referenced this issue Oct 5, 2012

Adrien Lamothe Update guides/source/action_mailer_basics.md
Setting config.action_mailer.raise_delivery_errors = true only raises email delivery errors if the email server is configured a certain way. You will have to consult the documentation for your particular email server. Refer to discussion at rails/rails#7473
3ad2120

@Alamoz Alamoz pushed a commit to Alamoz/docrails that referenced this issue Oct 5, 2012

Adrien Lamothe Update railties/lib/rails/generators/rails/app/templates/config/envir…
…onments/production.rb.tt

Setting config.action_mailer.raise_delivery_errors = true only raises email delivery errors if the external email server is configured a certain way. Refer to discussion at rails/rails#7473
d2f361d
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment