I programmed years before with .Net, Java, etc. and haven’t had any
exposure to Ruby yet. Since I have a background in CS, I can kinda
follow what’s going on but I’m stuck with this.
I have taken over support for a website within our company that allows
users to submit requests. When they submit a request, they are sent an
email through our Exchange server with the request details. I’m getting
an error in the Ruby code that sends the emails. Any help would be
appreciated.
I’ve attached a copy of the error and the ruby code where the error is
happening.
The call to “f.gets” is trying to read the next string from the IO
object (in this case it’s a TCPSocket). The docs say you’ll get nil when
you hit EOF. You can’t call #chomp (or most other methods) on NilClass
without it throwing up its hands and exiting.
I’m assuming you are getting EOF here because the socket connection has
been interrupted or dropped. Perhaps a router or firewall change is
related? Alternately, perhaps the peer (the guy on the other end of this
socket) is sending malformed messages. This is hard to debug without
knowing all of the pieces.
Have you got the debug flag turned on, and does it output anything to
the console? I would expect it to say something like;
srv> nil
… in which case the socket gets method is returning nil for whatever
reason. If you just wanted to ignore it, you could have it return an
empty string or something if l == nil and see what breaks further down
the line. Maybe the socket connection is going away, or there is nothing
more to read off the socket? I’m not familiar enough with Ruby’s socket
libraries or the Classes/ Methods therein sorry.
def readline(f)
l = f.gets
puts “srv> %s” % l if $debug
if l.kind_of?(String)
l.chomp!
end
l
end
1 you assume that gets always return something other than nil
2 if you accept nils, then convert it first to string before chomping
it or whatever…
Even better: drop method readline completely and use a loop with block:
def send_mail(to, subj, msg, filename=“”)
# establish socket
s = TCPSocket.new($host, $port)
ntlm = false
# handle host greeting
readline s
writeline s, "EHLO #{$host}"
s.each |line|
line.chomp!
ntlm ||= /^250-AUTH.+NTLM.*/ =~ line
break if /^250 / =~ line
end
Note also that you then must declare variable “ntlm” outside the loop
body.
You also need to change the way you work with the socket because it
will only be properly closed if all goes well. Your current code will
leak open sockets in case of errors and may eventually run out of file
descriptors if this is running longer. You either need to do
# establish socket
s = TCPSocket.new($host, $port)
begin
...
ensure
s.close
end
or simply use TCPSocket.open with block:
TCPSocket.open($host, $port) do |s|
…
end
Kind regards
robert
This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.