better error handling
This commit is contained in:
parent
0154d6292d
commit
9026140c4e
2 changed files with 89 additions and 97 deletions
|
|
@ -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
|
||||
begin
|
||||
first, last = get_group_info(server)
|
||||
return false if first == false
|
||||
if first
|
||||
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
|
||||
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,21 +187,20 @@ 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)
|
||||
reconnect(server)
|
||||
get_group_info(server)
|
||||
retry
|
||||
end
|
||||
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)
|
||||
raise TimeoutError, "Too many timeouts! (get_xhrd)\n" if timedout > 1
|
||||
reconnect(server)
|
||||
get_group_info(server)
|
||||
retry
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# if xhdr doesn't work, this should be used
|
||||
|
|
@ -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,21 +249,20 @@ 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)
|
||||
reconnect(server)
|
||||
get_group_info(server)
|
||||
retry
|
||||
end
|
||||
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)
|
||||
raise TimeoutError, "Too many timeouts! (get_body)\n" if timedout > 1
|
||||
reconnect(server)
|
||||
get_group_info(server)
|
||||
retry
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def get_group_body(subj)
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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,7 +247,6 @@ 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
|
||||
|
|
@ -266,10 +264,6 @@ def output_data(subject, mode, filename="", body="")
|
|||
@articles.group_update_newsrc(subject)
|
||||
@articles.save_newsrc unless @config[group].has_key?("-T") and @config[group]["-T"]
|
||||
end
|
||||
else
|
||||
return false
|
||||
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)
|
||||
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)
|
||||
output_data(i, mode, filename, body) if mode != false
|
||||
rescue Article::BodyError
|
||||
next
|
||||
end
|
||||
else
|
||||
print " Not complete: #{i}\n"
|
||||
end
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue