Net::ReadTimeout with #<socket:(closed)> Problem in mail gem in ruby 3.2 when attaching files in mail
May 24, 2023
kapilnakhwa
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.
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}%