end
raise
end
- rescue Net, SocketError, Net::IMAP::Error, SystemCallError => e
+ rescue SocketError, Net::IMAP::Error, SystemCallError, IOError => e
raise FatalSourceError, "While communicating with IMAP server: #{e.message}"
end
end
end
[ids.sort, ids_to_fns]
end
- rescue SystemCallError => e
+ rescue SystemCallError, IOError => e
raise FatalSourceError, "Problem scanning Maildir directories: #{e.message}."
end
fn = @ids_to_fns[id] or raise OutOfSyncSourceError, "No such id: #{id.inspect}."
begin
File.open(fn) { |f| yield f }
- rescue SystemCallError => e
+ rescue SystemCallError, IOError => e
raise FatalSourceError, "Problem reading file for id #{id.inspect}: #{fn.inspect}: #{e.message}."
end
end
when String
uri = URI(uri_or_fp)
raise ArgumentError, "not an mbox uri" unless uri.scheme == "mbox"
- raise ArgumentError, "mbox uri cannot have a host: #{uri.host}" if uri.host
+ raise ArgumentError, "mbox uri ('#{uri}') cannot have a host: #{uri.host}" if uri.host
## heuristic: use the filename as a label, unless the file
## has a path that probably represents an inbox.
@labels << File.basename(uri.path).intern unless File.dirname(uri.path) =~ /\b(var|usr|spool)\b/
next_offset = @f.tell
end
end
- rescue SystemCallError => e
+ rescue SystemCallError, IOError => e
raise FatalSourceError, "Error reading #{@f.path}: #{e.message}"
end
@file_size = nil
@offset = 0
@say_id = nil
- @broken_msg = nil
@shell = nil
@shell_mutex = nil
@buf_mutex = Mutex.new
end
def to_s; "mbox+ssh://#@host/#@fn"; end ## TODO: remove this EVILness
- def broken?; !@broken_msg.nil?; end
def connect
do_remote nil
end
def unsafe_connect
- raise SSHFileError, @broken_msg if broken?
return if @shell
@key = [@host, @ssh_opts[:username]]
@shell, @shell_mutex = @@shells_mutex.synchronize do
unless @@shells.member? @key
say "Opening SSH connection to #{@host} for #@fn..."
- #raise SSHFileError, "simulated SSH file error"
session = Net::SSH.start @host, @ssh_opts
say "Starting SSH shell..."
@@shells[@key] = [session.shell.sync, Mutex.new]
end
@@shells[@key]
end
-
+
say "Checking for #@fn..."
@shell_mutex.synchronize { raise Errno::ENOENT, @fn unless @shell.test("-e #@fn").status == 0 }
ensure
def do_remote cmd, expected_size=0
retries = 0
result = nil
- begin
- begin
- unsafe_connect
- if cmd
- # MBox::debug "sending command: #{cmd.inspect}"
- result = @shell_mutex.synchronize { x = @shell.send_command cmd; sleep 0.25; x }
- raise SSHFileError, "Failure during remote command #{cmd.inspect}: #{(result.stderr || result.stdout || "")[0 .. 100]}" unless result.status == 0
- end
- ## Net::SSH::Exceptions seem to happen every once in a while for
- ## no good reason.
- rescue Net::SSH::Exception, *RECOVERABLE_ERRORS
- if (retries += 1) <= 3
- @@shells_mutex.synchronize do
- @shell = nil
- @@shells[@key] = nil
- end
- retry
+ begin
+ unsafe_connect
+ if cmd
+ # MBox::debug "sending command: #{cmd.inspect}"
+ result = @shell_mutex.synchronize { x = @shell.send_command cmd; sleep 0.25; x }
+ raise SSHFileError, "Failure during remote command #{cmd.inspect}: #{(result.stderr || result.stdout || "")[0 .. 100]}" unless result.status == 0
+ end
+ ## Net::SSH::Exceptions seem to happen every once in a while for
+ ## no good reason.
+ rescue Net::SSH::Exception, *RECOVERABLE_ERRORS
+ if (retries += 1) <= 3
+ @@shells_mutex.synchronize do
+ @shell = nil
+ @@shells[@key] = nil
end
- raise
+ retry
end
- rescue Net::SSH::Exception, SSHFileError, SystemCallError => e
- @broken_msg = e.message
raise
end
module Redwood
module MBox
-## this is slightly complicated because SSHFile (and thus @f or
-## @loader) can throw a variety of exceptions, and we need to catch
-## those, reraise them as SourceErrors, and set ourselves as broken.
-
class SSHLoader < Source
attr_accessor :username, :password
def filename; @parsed_uri.path[1..-1] end
def next
- return if broken?
safely do
offset, labels = @loader.next
self.cur_offset = @loader.cur_offset # superclass keeps @cur_offset which is used by yaml
def safely
begin
yield
- rescue Net::SSH::Exception, SocketError, SSHFileError, SystemCallError => e
+ rescue Net::SSH::Exception, SocketError, SSHFileError, SystemCallError, IOError => e
m = "error communicating with SSH server #{host} (#{e.class.name}): #{e.message}"
- Redwood::log m
- self.broken_msg = @loader.broken_msg = m
- raise SourceError, m
+ raise FatalSourceError, m
end
end
begin
File.open(fn, "w") { |f| yield f }
BufferManager.flash "Successfully wrote #{fn}."
- rescue SystemCallError => e
+ rescue SystemCallError, IOError => e
BufferManager.flash "Error writing to file: #{e.message}"
end
end