Net::ReadTimeout with #<socket:(closed)> Problem in mail gem in ruby 3.2 when attaching files in mail

May 24, 2023
Recently I was building a plain sinatra app to receive a webhook and Json parse the payload so that I can Email some files recieved via the payload in webhook. 
Plain old ruby , required sinatra , json and mail gem. Fired up the server and started testing via CLI using CURL. 
Received an interesting error. 
curl -X POST -H 'Content-Type: application/json' -d '{"email": "info@hikuro.com"}' http://lvh.me:4567/downloads/developers_playbook
Net::ReadTimeout: Net::ReadTimeout with #<Socket:(closed)>
	/Users/kapilnakhwa/.rvm/rubies/ruby-3.2.1/lib/ruby/3.2.0/net/protocol.rb:229:in `rbuf_fill'
..................................................................................................................................
..................................................................................................................................

This was the configuration being used in the ruby file main.rb 
require 'sinatra'
require 'mail'
require 'dotenv/load'
require 'json'

Mail.defaults do
  delivery_method :smtp, {
    address: 'smtp.gmail.com',
    port: 587,
    domain: 'rumrail.com',
    user_name: ENV['GMAIL_USERNAME'] ,
    password: ENV['GMAIL_PASSWORD'],
    authentication: 'plain',
    enable_starttls_auto: true
  }
end

post '/downloads/developers_playbook' do
  request_body = JSON.parse(request.body.read)
  recipient_email = request_body['email']
  puts recipient_email
# Create a new email message
  mail = Mail.new do
    from    'XXXX'
    to      recipient_email
    subject 'Your Requested Developer Playbook'
    body    'Thank you for your interest in Rumrail! Please find attached the Developer Playbook you requested.'
    add_file 'assets/developer_playbook.pdf'
  end
  # Send the email
  puts "sending mail"
  mail.deliver
  puts "Mail sent"
  # Return a success message
  content_type :json
  {message: 'success', status: 200}.to_json
end

I was some time going through the problem and realized the error was nto from the mail gem but rather underlying Net::SMTP class being used by net smtp gem.
After going through read me file for the Mail gem and the going through issues,
Found on this PR that was merged.
https://github.com/mikel/mail/pull/892/commits/fcdb7faef677b698cd078bec732f0dc15edaaed3

It seems they were passing in two configurations read_timeout and open_timeout, to the underlying dependencies but was not document in ReadMe file in the mail gem, 
so changed the configuration in main.rb to 
Mail.defaults do
  delivery_method :smtp, {
    address: 'smtp.gmail.com',
    port: 587,
    domain: 'rumrail.com',
    user_name: ENV['GMAIL_USERNAME'] ,
    password: ENV['GMAIL_PASSWORD'],
    authentication: 'plain',
    enable_starttls_auto: true,
    read_timeout: 300
  }
end

And the problem is fixed for now, I knw 300 secs in not ideal and this process should itself be handled by a queue, But hey this is for less than 20 assumed mails a week. 
❯ curl -X POST -H 'Content-Type: application/json' -d '{"email": "info@hikuro.com"}' http://lvh.me:4567/downloads/developers_playbook
{"message":"success","status":200}%