Skip to content

Restore SMTP IO sync even when DATA flushing fails - #102

Open
OskarEichler wants to merge 2 commits into
ruby:masterfrom
OskarEichler:codex/data-smtp
Open

Restore SMTP IO sync even when DATA flushing fails#102
OskarEichler wants to merge 2 commits into
ruby:masterfrom
OskarEichler:codex/data-smtp

Conversation

@OskarEichler

Copy link
Copy Markdown

Summary

Restore the original IO sync setting in an ensure around DATA flushing. A flush exception currently bypasses restoration and leaves the IO in buffered mode. Keep the existing flush operation and exception precedence.

Reproduction

require 'net/smtp'
io = Object.new
class << io
  attr_accessor :sync
  def flush = raise(IOError, 'synthetic flush failure')
end
io.sync = true
socket = Struct.new(:io).new(io)
def socket.write_message(*) = nil
smtp = Net::SMTP.new('example.invalid', starttls: false)
smtp.instance_variable_set(:@socket, socket)
smtp.define_singleton_method(:get_response) { |_| Net::SMTP::Response.parse('354 continue') }
begin
  smtp.data('local fixture')
rescue IOError
end
p io.sync # before: false; after: true

Verification

  • 64 focused checks cover initial sync true/false, String/block message forms, write/flush failures separately and together, successful messages, exactly one flush, and original error object identity. Four failed expectations before; zero after.
  • Existing rake test: 95 tests, 170 assertions, zero failures/errors, on baseline and this isolated branch, Ruby 4.0.6 via rbenv. Existing local TLS cases are included.
  • Supplemental RuboCop Lint has the same six existing findings; Ruby syntax and git diff --check pass. No new/modified repository tests, dependencies or workflow settings.
  • Independent branch based on c2e9102e1f199a5a10e5261a776d752e64cc130f; runtime matches released 0.5.1. External focused checks were used under the consumer repository's no-new-tests policy.

Compatibility and limits

No signature or protocol change. The original sync mode is now restored after flush failure. A flush error still takes precedence over an earlier write error; this patch does not make a failed SMTP exchange resumable. A sync= implementation that itself raises remains outside this fix. Other Ruby/OS runtimes were not run locally. No production or external SMTP delivery was used. Maintainer CI status is separate from these local checks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant