Project

General

Profile

Bug #13018

end of file reached (EOFError) from SMTP

Added by tobymurray-nanometrics (Toby Murray) over 2 years ago. Updated about 1 month ago.

Status:
Closed
Priority:
Normal
Target version:
-
ruby -v:
ruby 2.4.0preview3 (2016-11-07 trunk 56661) [x86_64-linux]
[ruby-core:78550]

Description

Originally filed against Rails: https://github.com/rails/rails/issues/27298

require 'net/smtp'

real_email_address = '' # This needs to actually be a real account
real_email_password = '' # This needs to actually be the corresponding password

#line 96 of mail-2.2.7/lib/mail/network/delivery_methods/smtp.rb
smtp = Net::SMTP.new('smtp-relay.gmail.com', 587)
smtp.enable_starttls_auto if smtp.respond_to?(:enable_starttls_auto)
# smtp.set_debug_output $stderr # Uncomment this line to see SMTP session details

smtp.start('does-not-matter', real_email_address, real_email_password, 'Login') do |smtp|
  smtp.sendmail('Message does not matter', 'inconsistent from address', 'does not matter')
end

Yields end of file reached (EOFError). From the discussion there, it seems like the SMTP relay is inappropriately killing the session, but I believe it should be wrapped in a different error - e.g. Net:SMTPError. As it stands, there's no stack trace available or this error, so it just appears and is difficult to find.

Tried with 2.4.0-preview3, 2.3.3, and 2.3.1 (as well as jruby-9.1.6.0) and all had the same behavior

Associated revisions

Revision 58935eb8
Added by shugo (Shugo Maeda) over 2 years ago

lib/net/protocol.rb: preserve backtrace information

BufferedIO#rbuf_fill should preserve backtrace information when raising
EOFError. Otherwise, users get confused when EOFError is leaked out from
Net::SMTP etc. [ruby-core:78550] [Bug #13018]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@57311 b2dd03c8-39d4-4d8f-98ff-823fe69b080e

Revision 57311
Added by shugo (Shugo Maeda) over 2 years ago

lib/net/protocol.rb: preserve backtrace information

BufferedIO#rbuf_fill should preserve backtrace information when raising
EOFError. Otherwise, users get confused when EOFError is leaked out from
Net::SMTP etc. [ruby-core:78550] [Bug #13018]

Revision 57311
Added by shugo (Shugo Maeda) over 2 years ago

lib/net/protocol.rb: preserve backtrace information

BufferedIO#rbuf_fill should preserve backtrace information when raising
EOFError. Otherwise, users get confused when EOFError is leaked out from
Net::SMTP etc. [ruby-core:78550] [Bug #13018]

Revision 57311
Added by shugo (Shugo Maeda) over 2 years ago

lib/net/protocol.rb: preserve backtrace information

BufferedIO#rbuf_fill should preserve backtrace information when raising
EOFError. Otherwise, users get confused when EOFError is leaked out from
Net::SMTP etc. [ruby-core:78550] [Bug #13018]

History

Updated by tobymurray-nanometrics (Toby Murray) over 2 years ago

  • Description updated (diff)

Fix typo

Updated by shyouhei (Shyouhei Urabe) over 2 years ago

  • Assignee set to shugo (Shugo Maeda)
  • Status changed from Open to Assigned

Updated by shugo (Shugo Maeda) over 2 years ago

  • Assignee changed from shugo (Shugo Maeda) to normalperson (Eric Wong)

Toby Murray wrote:

Yields end of file reached (EOFError). From the discussion there, it seems like the SMTP relay is inappropriately killing the session, but I believe it should be wrapped in a different error - e.g. Net:SMTPError. As it stands, there's no stack trace available or this error, so it just appears and is difficult to find.

The reason why no stack trace is available is the following code introduced by r50219:

    # callers do not care about backtrace, so avoid allocating for it
    raise EOFError, 'end of file reached', []

Eric, is it intentional that stack trace is lost in this case?

Speaking of Net::SMTP, EOFError is raised in do_finish, so it may be better to ignore.
However, it's too late to change the behavior in Ruby 2.4.0, I think.

Updated by tobymurray-nanometrics (Toby Murray) over 2 years ago

Someone has commented on the Rails issue here: https://github.com/rails/rails/issues/27298#issuecomment-269980037 that this is one of a handful of errors that leak out. Not sure whether the ones mentioned there mean much in this context, but worth validation I imagine.

Shugo Maeda wrote:

The reason why no stack trace is available is the following code introduced by r50219:

    # callers do not care about backtrace, so avoid allocating for it
    raise EOFError, 'end of file reached', []

I care...

Updated by normalperson (Eric Wong) over 2 years ago

shugo@ruby-lang.org wrote:

Assignee changed from Shugo Maeda to Eric Wong

Toby Murray wrote:

Yields end of file reached (EOFError). From the discussion there, it seems like the SMTP relay is inappropriately killing the session, but I believe it should be wrapped in a different error - e.g. Net:SMTPError. As it stands, there's no stack trace available or this error, so it just appears and is difficult to find.

The reason why no stack trace is available is the following code introduced by r50219:

    # callers do not care about backtrace, so avoid allocating for it
    raise EOFError, 'end of file reached', []

Eric, is it intentional that stack trace is lost in this case?

(Sorry, I missed this earlier, feel free to Cc: me directly if I
fail to respond).

Yes, it was my intention to avoid allocations since I remember
callers would not care; but it looks like I was wrong...

Speaking of Net::SMTP, EOFError is raised in do_finish, so it may be better to ignore.
However, it's too late to change the behavior in Ruby 2.4.0, I think.

If caller needs backtrace, then yes, we should preserve stack
trace. EOFError is much rarer than IO::Wait*able, however, so
less of a performance problem.

Updated by shugo (Shugo Maeda) over 2 years ago

Toby Murray wrote:

Someone has commented on the Rails issue here: https://github.com/rails/rails/issues/27298#issuecomment-269980037 that this is one of a handful of errors that leak out. Not sure whether the ones mentioned there mean much in this context, but worth validation I imagine.

Other libraries also have the same behavior.

 # callers do not care about backtrace, so avoid allocating for it

I care...

Me too.

Can we close this issue by fixing backtrace information?
If you want Net::SMTPError, please file another ticket as a feature request.

Eric Wong wrote:

The reason why no stack trace is available is the following code introduced by r50219:

    # callers do not care about backtrace, so avoid allocating for it
    raise EOFError, 'end of file reached', []

Eric, is it intentional that stack trace is lost in this case?

(Sorry, I missed this earlier, feel free to Cc: me directly if I
fail to respond).

Yes, it was my intention to avoid allocations since I remember
callers would not care; but it looks like I was wrong...

Speaking of Net::SMTP, EOFError is raised in do_finish, so it may be better to ignore.
However, it's too late to change the behavior in Ruby 2.4.0, I think.

If caller needs backtrace, then yes, we should preserve stack
trace. EOFError is much rarer than IO::Wait*able, however, so
less of a performance problem.

May I fix it to preserve the backtrace information, or would you?

Updated by normalperson (Eric Wong) over 2 years ago

Shugo Maeda shugo@ruby-lang.org wrote:

May I fix it to preserve the backtrace information, or would you?

Sure, you can :)

#8

Updated by shugo (Shugo Maeda) over 2 years ago

  • Status changed from Assigned to Closed

Applied in changeset r57311.


lib/net/protocol.rb: preserve backtrace information

BufferedIO#rbuf_fill should preserve backtrace information when raising
EOFError. Otherwise, users get confused when EOFError is leaked out from
Net::SMTP etc. [ruby-core:78550] [Bug #13018]

Updated by shugo (Shugo Maeda) over 2 years ago

Shugo Maeda wrote:

Can we close this issue by fixing backtrace information?

Closed by r57311, but feel free to reopen if you don't like it.

Updated by Nakilon (Victor Maslov) about 1 month ago

Excuse me, why isn't it fixed in 2.4? Does it break something?
I've probably misconfigured ports around my docker environment (it's yet to be investigated) and was now very confused with this. Had to run the program a lot of times, resettings breakpoints in byebug until I've found this.

Also available in: Atom PDF