From: Giuseppe Bilotta Date: Wed, 5 Jul 2006 16:18:18 +0000 (+0000) Subject: Improve debug output for multiline error messages. Improve exception handling for... X-Git-Url: https://git.netwichtig.de/gitweb/?a=commitdiff_plain;h=602da36df14da2cf1bab2b440e8f39018bba0b3f;p=user%2Fhenk%2Fcode%2Fruby%2Frbot.git Improve debug output for multiline error messages. Improve exception handling for socket and connection problems. Stop sending pings when disconnected. --- diff --git a/lib/rbot/ircbot.rb b/lib/rbot/ircbot.rb index 8f0a2646..0cfc3f12 100644 --- a/lib/rbot/ircbot.rb +++ b/lib/rbot/ircbot.rb @@ -7,7 +7,9 @@ $debug = false unless $debug def debug(message=nil) if ($debug && message) stamp = Time.now.strftime("%Y/%m/%d %H:%M:%S") - print "D: [#{stamp}] #{message}\n" + message.to_s.each_line { |l| + $stdout.puts "D: [#{stamp}] #{l}" + } $stdout.flush end #yield @@ -38,20 +40,20 @@ module Irc class IrcBot # the bot's current nickname attr_reader :nick - + # the bot's IrcAuth data attr_reader :auth - + # the bot's BotConfig data attr_reader :config - + # the botclass for this bot (determines configdir among other things) attr_reader :botclass - + # used to perform actions periodically (saves configuration once per minute # by default) attr_reader :timer - + # bot's Language data attr_reader :lang @@ -79,7 +81,7 @@ class IrcBot :wizard => true) BotConfig.register BotConfigIntegerValue.new('server.port', :default => 6667, :type => :integer, :requires_restart => true, - :desc => "What port should the bot connect to?", + :desc => "What port should the bot connect to?", :validate => Proc.new {|v| v > 0}, :wizard => true) BotConfig.register BotConfigStringValue.new('server.password', :default => false, :requires_restart => true, @@ -124,7 +126,7 @@ class IrcBot puts "data directory '#{Config::datadir}' not found, did you setup.rb?" exit 2 end - + botclass = "#{Etc.getpwuid(Process::Sys.geteuid)[:dir]}/.rbot" unless botclass #botclass = "#{ENV['HOME']}/.rbot" unless botclass botclass = File.expand_path(botclass) @@ -138,7 +140,7 @@ class IrcBot end FileUtils.cp_r Config::datadir+'/templates', botclass end - + Dir.mkdir("#{botclass}/logs") unless File.exist?("#{botclass}/logs") Dir.mkdir("#{botclass}/registry") unless File.exist?("#{botclass}/registry") @@ -179,11 +181,11 @@ class IrcBot log "MOTD: #{line}", "server" } } - @client[:nicktaken] = proc { |data| + @client[:nicktaken] = proc { |data| nickchg "#{data[:nick]}_" @plugins.delegate "nicktaken", data[:nick] } - @client[:badnick] = proc {|data| + @client[:badnick] = proc {|data| puts "WARNING, bad nick (#{data[:nick]})" } @client[:ping] = proc {|data| @@ -265,7 +267,7 @@ class IrcBot onpart(m) } @client[:kick] = proc {|data| - m = KickMessage.new(self, data[:source], data[:target],data[:channel],data[:message]) + m = KickMessage.new(self, data[:source], data[:target],data[:channel],data[:message]) onkick(m) } @client[:invite] = proc {|data| @@ -325,7 +327,7 @@ class IrcBot begin @socket.connect rescue => e - raise "failed to connect to IRC server at #{@config['server.name']} #{@config['server.port']}: " + e + raise e.class, "failed to connect to IRC server at #{@config['server.name']} #{@config['server.port']}: " + e end @socket.puts "PASS " + @config['server.password'] if @config['server.password'] @socket.puts "NICK #{@nick}\nUSER #{@config['irc.user']} 4 #{@config['server.name']} :Ruby bot. (c) Tom Gilbert" @@ -338,7 +340,7 @@ class IrcBot begin connect @timer.start - + while @socket.connected? if @socket.select break unless reply = @socket.gets @@ -351,8 +353,9 @@ class IrcBot #rescue TimeoutError, SocketError => e rescue SystemExit exit 0 - rescue TimeoutError => e - puts e + rescue TimeoutError, SocketError => e + puts "#{e.class}: #{e}" + debug e.backtrace.join("\n") rescue Exception => e puts "network exception: #{e.inspect}" puts e.backtrace.join("\n") @@ -362,17 +365,18 @@ class IrcBot puts e.backtrace.join("\n") exit 2 end - + puts "disconnected" - @last_ping = nil + + stop_server_pings @channels.clear @socket.clearq - + puts "waiting to reconnect" sleep @config['server.reconnect_wait'] end end - + # type:: message type # where:: message target # message:: message text @@ -456,7 +460,7 @@ class IrcBot @logs[where].puts "[#{stamp}] #{message}" #debug "[#{stamp}] <#{where}> #{message}" end - + # set topic of channel +where+ to +topic+ def topic(where, topic) sendq "TOPIC #{where} :#{topic}" @@ -494,7 +498,7 @@ class IrcBot @socket.shutdown puts "rbot quit (#{message})" end - + # message:: optional IRC quit message # quit IRC, shutdown the bot def quit(message=nil) @@ -529,7 +533,7 @@ class IrcBot @plugins.rescan @keywords.rescan end - + # channel:: channel to join # key:: optional channel key if channel is +s # join a channel @@ -555,7 +559,7 @@ class IrcBot def mode(channel, mode, target) sendq "MODE #{channel} #{mode} #{target}" end - + # m:: message asking for help # topic:: optional topic help is requested for # respond to online help requests @@ -597,16 +601,7 @@ class IrcBot # we'll ping the server every 30 seconds or so, and expect a response # before the next one come around.. def start_server_pings - @last_ping = nil - # stop existing timers if running - unless @ping_timer.nil? - @timer.remove @ping_timer - @ping_timer = nil - end - unless @pong_timer.nil? - @timer.remove @pong_timer - @pong_timer = nil - end + stop_server_pings return unless @config['server.ping_timeout'] > 0 # we want to respond to a hung server within 30 secs or so @ping_timer = @timer.add(30) { @@ -622,15 +617,27 @@ class IrcBot @socket.shutdown rescue debug "couldn't shutdown connection (already shutdown?)" - ensure - raise TimeoutError, "no PONG from server in #{diff} seconds" end @last_ping = nil + raise TimeoutError, "no PONG from server in #{diff} seconds" end end } end + def stop_server_pings + @last_ping = nil + # stop existing timers if running + unless @ping_timer.nil? + @timer.remove @ping_timer + @ping_timer = nil + end + unless @pong_timer.nil? + @timer.remove @pong_timer + @pong_timer = nil + end + end + private # handle help requests for "core" topics @@ -849,7 +856,7 @@ class IrcBot # exit 2 end end - + # delegate to plugins @plugins.delegate("listen", m) @plugins.delegate("part", m) diff --git a/lib/rbot/ircsocket.rb b/lib/rbot/ircsocket.rb index 6ff93725..6a5f281a 100644 --- a/lib/rbot/ircsocket.rb +++ b/lib/rbot/ircsocket.rb @@ -9,16 +9,16 @@ module Irc class IrcSocket # total number of lines sent to the irc server attr_reader :lines_sent - + # total number of lines received from the irc server attr_reader :lines_received - + # delay between lines sent attr_reader :sendq_delay - + # max lines to burst attr_reader :sendq_burst - + # server:: server to connect to # port:: IRCd port # host:: optional local host to bind to (ruby 1.7+ required) @@ -48,7 +48,7 @@ module Irc @sendq_burst = 4 end end - + def connected? !@sock.nil? end @@ -56,7 +56,8 @@ module Irc # open a TCP connection to the server def connect if connected? - shutdown + debug "reconnecting socket while connected" + shutdown end if(@host) begin @@ -70,7 +71,7 @@ module Irc end else @sock=TCPSocket.new(@server, @port) - end + end @qthread = false @qmutex = Mutex.new @sendq = Array.new @@ -106,15 +107,19 @@ module Irc # get the next line from the server (blocks) def gets + if @sock.nil? + debug "socket get attempted while closed" + return nil + end begin - reply = @sock.gets - @lines_received += 1 - reply.strip! if reply - debug "RECV: #{reply.inspect}" - return reply + reply = @sock.gets + @lines_received += 1 + reply.strip! if reply + debug "RECV: #{reply.inspect}" + return reply rescue => e - debug "socket get failed: #{e}" - return nil + debug "socket get failed: #{e.inspect}" + return nil end end @@ -183,7 +188,7 @@ module Irc end private - + # same as puts, but expects to be called with a mutex held on @qmutex def puts_critical(message) # debug "in puts_critical"