From 9026140c4e1f868212e2ffe9a83a089bd4a0b452 Mon Sep 17 00:00:00 2001 From: Ward Wouts Date: Wed, 3 Jul 2002 22:18:40 +0000 Subject: [PATCH] better error handling --- trunk/ripnews/news/article.rb | 125 ++++++++++++++++------------------ trunk/ripnews/ripnews.rb | 61 +++++++++-------- 2 files changed, 89 insertions(+), 97 deletions(-) diff --git a/trunk/ripnews/news/article.rb b/trunk/ripnews/news/article.rb index 4c9d5cf..165bb1f 100644 --- a/trunk/ripnews/news/article.rb +++ b/trunk/ripnews/news/article.rb @@ -15,6 +15,11 @@ require 'news/newsrc' require 'tempfile' require 'timeout' +class ArticleError < RuntimeError; end +class ReconnectError < ArticleError; end +class GroupInfoError < ArticleError; end +class BodyError < ArticleError; end + class Article Debuglevel = 0 @@ -41,25 +46,21 @@ def initialize(nntpservers, groupname, newsrc="~/.newsrc") @connections[server]["newsrc"] = News::Newsrc.new("#{newsrc}.#{server}") set_skip_ids(server, @connections[server]["newsrc"].marked_articles(@group)) rescue SocketError - print "Connection to #{server} failed, removing from server list...\n" - @connections.delete(server) - @serverlist.delete(server) + print "Connection to #{server} failed\n" + del_server(server) end } end def reconnect(server) - print "Trying to reconnect to #{server}...\n" begin @connections[server]["nntp"] = Net::NNTP.new(server) rescue SocketError - print "Connection to #{server} failed, removing from server list...\n" - @connections.delete(server) - @serverlist.delete(server) - return false + print "Reconnect to #{server} failed\n" + del_server(server) + raise ReconnectError end print "Succesfully reconnected to #{server}\n" - return true end def add(messid, id, server, subject) @@ -75,29 +76,32 @@ def add(messid, id, server, subject) @grouped = false end +def del_server(server) + print "Removing server #{server} from list\n" + @connections.delete(server) + @serverlist.delete(server) +end + def get_articles(cachedir=false) for server in @connections.keys - first, last = get_group_info(server) - return false if first == false - if first + begin + first, last = get_group_info(server) + rescue ReconnectError, GroupInfoError + del_server(server) + next + end + if first <= last @connections[server]["first"] = first ? first : 0 @connections[server]["last"] = last ? last : 0 else - print "Error selecting @group on server #{server}, removing from server list...\n" - @connections.delete(server) - @serverlist.delete(server) + print " First article has higher number than last article on server #{server}.\n" + del_server(server) end end read_cache(cachedir) for server in @connections.keys print " reading articles from server: #{server}\n" - if @connections[server]["first"] > @connections[server]["last"] - print " First article has higher number than last article on server #{server}.\n" - print " Skipping...\n" - next - else - range = Set::IntSpan.new("#{@connections[server]["first"]}-#{@connections[server]["last"]}") - end + range = Set::IntSpan.new("#{@connections[server]["first"]}-#{@connections[server]["last"]}") rangelist = rechunk_runlist(range.diff(@connections[server]["skip_ids"]).run_list) print "rangelist: #{rangelist}\n" if Debuglevel >1 print "rangelist: #{rangelist.type.to_s}\n" if Debuglevel >1 @@ -105,10 +109,13 @@ def get_articles(cachedir=false) unless rangelist == nil or rangelist =~ /^$/ for i in rangelist.split(',') print "i: #{i}\n" if Debuglevel > 1 + begin resp, subj_lines = get_xhdr(server, i, "subject") - next unless resp resp, messid_lines = get_xhdr(server, i, "message-id") - next unless resp + rescue TimeoutError, ReconnectError, XhdrError, GroupInfoError + print "Caught: #{$!} reading from #{server}\n" + next + end art = {} subj_lines.collect{|x| @@ -139,30 +146,27 @@ def get_group_info(server) first = "" last = "" begin - if timedout > 1 - print "Too many timeouts! (get_group_info)\n" - return false - end timeout(30) do begin resp, count, first, last, name = @connections[server]["nntp"].group(@group) rescue Net::NNTP::RuntimeError - print "Couldn't open group: #{@group}\n" - print "Error: #{$!}\n" - return false + print "Got error \"#{$!}\" from #{server}\n" + raise GroupInfoError rescue Errno::EPIPE, Errno::ECONNRESET print "Caught Errno::EPIPE reading from server #{server}\n" print "Error: #{$!}\n" - retry if reconnect(server) + reconnect(server) + retry end end - return first, last if resp rescue TimeoutError - print "Time out, reconnecting to server\n" timedout += 1 - retry if reconnect(server) + raise TimeoutError, "Too many timeouts! (get_group_info)\n" if timedout > 1 + print "Time out, reconnecting to server...\n" + reconnect(server) + retry end - return false + return first, last end def get_xhdr(server, range, header) @@ -170,16 +174,12 @@ def get_xhdr(server, range, header) resp = "" lines = [] begin - if timedout > 1 - print "Too many timeouts! (get_xhdr)\n" - return false - end timeout(180) do begin resp, lines = @connections[server]["nntp"].xhdr(header, range) unless resp.to_i >= 200 and resp.to_i < 300 print "got response #{resp} while reading group #{@group} from #{server}\n" - return false + raise XhdrError end rescue Net::NNTP::RuntimeError print "Caught Net::NNTP::RuntimeError reading from server #{server}\n" @@ -187,20 +187,19 @@ def get_xhdr(server, range, header) rescue Errno::EPIPE, Errno::ECONNRESET print "Caught Errno::EPIPE reading from server #{server}\n" print "Error: #{$!}\n" - if reconnect(server) - return false unless get_group_info(server) - retry - end + reconnect(server) + get_group_info(server) + retry end end return resp, lines rescue TimeoutError print "Time out, reconnecting to server\n" timedout += 1 - if reconnect(server) - return false unless get_group_info(server) - retry - end + raise TimeoutError, "Too many timeouts! (get_xhrd)\n" if timedout > 1 + reconnect(server) + get_group_info(server) + retry end end @@ -240,10 +239,6 @@ def get_body(server, message) messid = "" list = [] begin - if timedout > 1 - print "Too many timeouts! (get_body)\n" - return false - end timeout(180) do begin resp, id, messid, list = @connections[server]["nntp"].body(message) @@ -254,20 +249,19 @@ def get_body(server, message) rescue Errno::EPIPE, Errno::ECONNRESET print "Caught Errno::EPIPE reading from server #{server}\n" print "Error: #{$!}\n" - if reconnect(server) - return false unless get_group_info(server) - retry - end + reconnect(server) + get_group_info(server) + retry end end return resp, id, messid, list rescue TimeoutError print "Time out, reconnecting to server\n" timedout += 1 - if reconnect(server) - return false unless get_group_info(server) - retry - end + raise TimeoutError, "Too many timeouts! (get_body)\n" if timedout > 1 + reconnect(server) + get_group_info(server) + retry end end @@ -293,8 +287,7 @@ def get_group_body(subj) i += 1 retry else - print "Message-id not on another server :( Skipping...\n" - return false + raise BodyError, "Message-id not on another server\n" end end end @@ -325,8 +318,7 @@ def get_group_body_first(subj) i += 1 retry else - print "Message-id not on another server :( Skipping...\n" - return false + raise BodyError, "Message-id not on another server\n" end end end @@ -356,8 +348,7 @@ def get_group_body_rest(subj, file=nil) i += 1 retry else - print "Message-id not on another server :( Skipping...\n" - return false + raise BodyError, "Message-id not on another server\n" end end end diff --git a/trunk/ripnews/ripnews.rb b/trunk/ripnews/ripnews.rb index 1801744..1c66b92 100755 --- a/trunk/ripnews/ripnews.rb +++ b/trunk/ripnews/ripnews.rb @@ -224,7 +224,6 @@ def get_multi(subj, group) return false else body = @articles.get_group_body_first(subj) - return false if body == false if @articles.is_uuencoded(body) or @articles.is_yencoded(body) file = Tempfile.new("riptmp", @config[group]["TEMPDIR"]) body.collect{|x| file.print "#{x}\n"} @@ -248,28 +247,23 @@ def get_multi(subj, group) end def output_data(subject, mode, filename="", body="") - if mode - group = @articles.get_groupname - print " mode: #{mode}\n" if Debuglevel > 0 - print " Filename: '#{filename}'\n" if Debuglevel > 0 - if @config[group].has_key?("-L") and @config[group]["-L"] - print "longname\n" if Debuglevel > 1 - outfile = subject - elsif @config[group].has_key?("-C") and @config[group]["-C"] - print "combinedname\n" if Debuglevel > 1 - outfile = "#{subject} [#{filename}]" - else - print "shortname\n" if Debuglevel > 1 - outfile = filename - end - if save_file("#{@config[group]["DATADIR"]}/#{group}", outfile, body) - @articles.group_update_newsrc(subject) - @articles.save_newsrc unless @config[group].has_key?("-T") and @config[group]["-T"] - end + group = @articles.get_groupname + print " mode: #{mode}\n" if Debuglevel > 0 + print " Filename: '#{filename}'\n" if Debuglevel > 0 + if @config[group].has_key?("-L") and @config[group]["-L"] + print "longname\n" if Debuglevel > 1 + outfile = subject + elsif @config[group].has_key?("-C") and @config[group]["-C"] + print "combinedname\n" if Debuglevel > 1 + outfile = "#{subject} [#{filename}]" else - return false + print "shortname\n" if Debuglevel > 1 + outfile = filename + end + if save_file("#{@config[group]["DATADIR"]}/#{group}", outfile, body) + @articles.group_update_newsrc(subject) + @articles.save_newsrc unless @config[group].has_key?("-T") and @config[group]["-T"] end - return true end def check_ext(filename, mode) @@ -303,10 +297,13 @@ end for group in @config.keys.sort print "Getting articles for #{group}\n" @articles = Article.new(@config[group]["NNTPSERVER"], group, @config[group]["NEWSRCNAME"]) - if @articles.get_articles(@config[group]["CACHEDIR"]) == false - @articles.quit - next - end +# begin + @articles.get_articles(@config[group]["CACHEDIR"]) +# rescue Article:: +# print "Caught something: #{$!}\n" +# @articles.quit +# next +# end unless FileTest.directory?("#{@config[group]["DATADIR"]}/#{group}") or Dir.mkdir("#{@config[group]["DATADIR"]}/#{group}", @config[group]["PERMISSION"].oct) @@ -319,12 +316,16 @@ for group in @config.keys.sort i =~ /#{@config[group]["-I"]}/ print "Match: #{i}\n" if Debuglevel > 0 if @articles.group_is_complete(i) - if @articles.group_is_singlepart(i) - mode, filename, body = get_single(i) - elsif @articles.group_is_multipart(i) - mode, filename, body = get_multi(i, group) + begin + if @articles.group_is_singlepart(i) + mode, filename, body = get_single(i) + elsif @articles.group_is_multipart(i) + mode, filename, body = get_multi(i, group) + end + output_data(i, mode, filename, body) if mode != false + rescue Article::BodyError + next end - output_data(i, mode, filename, body) else print " Not complete: #{i}\n" end