Rails 3.1.1中的ActionMailer无法发送邮件

3
我在使用ActionMailer发送邮件时遇到了错误。
Errno::ECONNREFUSED
    Connection refused - connect(2)

/Users/bhushan/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/net/smtp.rb:546:in `initialize'
/Users/bhushan/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/net/smtp.rb:546:in `open'
/Users/bhushan/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/net/smtp.rb:546:in `tcp_socket'
/Users/bhushan/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/net/smtp.rb:555:in `block in do_start'
/Users/bhushan/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/timeout.rb:58:in `timeout'
/Users/bhushan/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/timeout.rb:89:in `timeout'
/Users/bhushan/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/net/smtp.rb:555:in `do_start'
/Users/bhushan/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/net/smtp.rb:525:in `start'
/Users/bhushan/.rvm/gems/ruby-1.9.2-p290/gems/mail-2.3.0/lib/mail/network/delivery_methods/smtp.rb:128:in `deliver!'
/Users/bhushan/.rvm/gems/ruby-1.9.2-p290/gems/mail-2.3.0/lib/mail/message.rb:1989:in `do_delivery'
/Users/bhushan/.rvm/gems/ruby-1.9.2-p290/gems/mail-2.3.0/lib/mail/message.rb:230:in `block in deliver'
/Users/bhushan/.rvm/gems/ruby-1.9.2-p290/gems/actionmailer-3.1.1/lib/action_mailer/base.rb:432:in `block in deliver_mail'
/Users/bhushan/.rvm/gems/ruby-1.9.2-p290/gems/activesupport-3.1.1/lib/active_support/notifications.rb:53:in `block in instrument'
/Users/bhushan/.rvm/gems/ruby-1.9.2-p290/gems/activesupport-3.1.1/lib/active_support/notifications/instrumenter.rb:21:in `instrument'
/Users/bhushan/.rvm/gems/ruby-1.9.2-p290/gems/activesupport-3.1.1/lib/active_support/notifications.rb:53:in `instrument'
/Users/bhushan/.rvm/gems/ruby-1.9.2-p290/gems/actionmailer-3.1.1/lib/action_mailer/base.rb:430:in `deliver_mail'
/Users/bhushan/.rvm/gems/ruby-1.9.2-p290/gems/mail-2.3.0/lib/mail/message.rb:230:in `deliver'
/Users/bhushan/betterlabs_projects/companyplus_beta/cp_frontend/app/workers/set_crawling.rb:29:in `perform'

我在initializers目录下有一个名为setup_mail.rb的文件,其中包含了SMTP设置。
 ActionMailer::Base.smtp_settings = {
 address: "smtp.gmail.com",
 port: 587,
 domain: 'betterlabs.net',  
 user_name: 'policemerepiche@gmail.com',
 password:
 authentication: 'plain',
 enable_starttls_auto: true
 }

我的邮件发送方法

   def send_email(email)
begin
# attachments['result.csv'] = File.read(file)
 mail(to: "bhushanlodha@gmail.com", subject: "hey")
 puts "====Mail Sent===="
 rescue Exception=>e
 puts e.inspect
 end
end

development.rb

  config.action_mailer.delivery_method = :smtp

有什么线索可以解决问题吗?谢谢。


我假设你已经将 ActionMailer::Base.delivery_method 设置为 :smtp 了? - Alex Peattie
我在development.rb中设置了config.action_mailer.delivery_method = :smtp。 - Bhushan Lodha
你能直接连接到smtp.gmail.com:587吗?例如通过telnet? - Thilo
3个回答

6

我曾经遇到过同样的问题。当我的邮件发送器从Web进程或Rails控制台执行时,可以正常地发送电子邮件,但如果它们被排队在工作进程中发送,则会引发Errno :: ECONNREFUSED异常。

我也使用初始化程序来设置配置。所有关于它的内容都像是SMTP设置在某种程度上被省略了,但只有在工作进程运行时才会出现这种情况。

最终,我将以下代码添加到邮件发送器中:

m = mail(to: "herpderp@example.com", subject: "Example")
puts m.to_yaml
return m

这表明邮件实例内部存在一个smtp设置对象(或从其中引用,并包含在to_yaml中),而且该smtp设置对象没有我在初始化器中声明的smtp设置。以下是摘录:

settings:
  :address: localhost
  :port: 25
  :domain: localhost.localdomain
  :user_name: 
  :password: 
  :authentication: 
  :enable_starttls_auto: true
  :openssl_verify_mode: 
  :ssl: 
  :tls: 

显然这是不正确的。此外,从同一声明中打印Rails.application.config.action_mailer.smtp_settings,将打印正确的设置
为了缩小可能性范围,当然我把我的设置声明移回development.rb,下一次这些设置在我的worker的stdout上打印时,它们是正确的,并且邮件按预期发送。
所以我不能说我完全理解初始值设定项何时如何处理,因为我对Rails核心模块的深度没有那么多的可见性,但我可以说,在那里的某个地方,由于邮件实例从全局配置中检索smtp设置的方式,初始化程序与环境文件中的声明方式/时间之间存在差异。
对我来说学到了教训。不要超出初始化程序类的标准Rails配置标准。一旦我把配置移回development.rb,一切都按预期工作了。也许其他人可以帮助解释环境rb文件和初始化程序之间发生了什么。

顺便提一下,我正在使用的Rails版本是3.2.11。 - a moose
3
非常感谢您的分享!我遇到了和你一模一样的情况,一度感到头疼不已。在你的帮助下并进一步调查后,我找到了原因:当从YML文件加载你的邮件设置时,键是字符串,而action_mailer并不喜欢这种情况。这个实现方法非常可行(在你的环境文件中): config.action_mailer.smtp_settings = YAML.load_file("#{::Rails.root}/config/mailer.yml")[::Rails.env] 接着使用 config.action_mailer.smtp_settings.symbolize_keys! - Benj
谢谢!我以为我疯了。我的初始化器允许其他的delivery_method值和/或散列(例如sendmail_settings或file_settings),因此对于加载的YML文件的每一对,我会执行ActionMailer::Base.send("#{key}=", value.is_a?(Hash) ? value.symbolize_keys! : value ) - Jake Vose
@Benj:谢谢你的评论!!三年后,symbolize_keys!让我节省了数小时的挫败感。 - istrasci

2
正如Thilo所说,明显的测试是确定您是否可以连接到Gmail服务器:
$ telnet smtp.gmail.com 587
Trying 74.125.53.108...
Connected to gmail-smtp-msa.l.google.com.
Escape character is '^]'.
220 mx.google.com ESMTP ft1sm69312925igc.3

如果您可以连接,则在引导过程中未捕获您的设置。我会检查您实际连接到哪里-请在smtp代码中添加一些puts语句(大约在第546行左右)。
/Users/bhushan/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/net/smtp.rb

1
请检查你在开始 ActionMailer 类中定义的 :from 键。

我在:from方法中写了名字而不是电子邮件。这很有帮助! - Bhushan Lodha

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接