duplicity-team team mailing list archive
-
duplicity-team team
-
Mailing list archive
-
Message #00435
[Merge] lp:~mterry/duplicity/backend-log-codes3 into lp:duplicity
Michael Terry has proposed merging lp:~mterry/duplicity/backend-log-codes3 into lp:duplicity.
Requested reviews:
duplicity-team (duplicity-team)
--
https://code.launchpad.net/~mterry/duplicity/backend-log-codes3/+merge/42759
Your team duplicity-team is requested to review the proposed merge of lp:~mterry/duplicity/backend-log-codes3 into lp:duplicity.
=== modified file 'duplicity/backends/giobackend.py'
--- duplicity/backends/giobackend.py 2010-11-20 15:39:00 +0000
+++ duplicity/backends/giobackend.py 2010-12-04 22:17:53 +0000
@@ -29,6 +29,7 @@
import duplicity.backend
from duplicity import log
from duplicity import globals
+from duplicity import util
from duplicity.errors import * #@UnusedWildImport
from duplicity.util import exception_traceback
@@ -88,10 +89,24 @@
% str(e), log.ErrorCode.connection_failed)
loop.quit()
+ def handle_error(self, e, op, file1=None, file2=None):
+ code = log.ErrorCode.backend_error
+ if isinstance(e, gio.Error):
+ if e.code == gio.ERROR_PERMISSION_DENIED:
+ code = log.ErrorCode.backend_permission_denied
+ elif e.code == gio.ERROR_NOT_FOUND:
+ code = log.ErrorCode.backend_not_found
+ elif e.code == gio.ERROR_NO_SPACE:
+ code = log.ErrorCode.backend_no_space
+ extra = ' '.join([util.escape(x) for x in [file1, file2] if x])
+ extra = ' '.join([op, extra])
+ log.FatalError(str(e), code, extra)
+
def copy_progress(self, *args, **kwargs):
pass
- def copy_file(self, source, target):
+ def copy_file(self, op, source, target):
+ exc = None
for n in range(1, globals.num_retries+1):
log.Info(_("Writing %s") % target.get_parse_name())
try:
@@ -103,8 +118,8 @@
% (target.get_parse_name(), n, e.__class__.__name__, str(e)))
log.Debug("Backtrace of previous error: %s"
% exception_traceback())
- raise BackendException(_("Could not copy %s to %s") % (source.get_parse_name(),
- target.get_parse_name()))
+ exc = e
+ self.handle_error(exc, op, source.get_parse_name(), target.get_parse_name())
def put(self, source_path, remote_filename = None):
"""Copy file to remote"""
@@ -112,19 +127,22 @@
remote_filename = source_path.get_filename()
source_file = gio.File(path=source_path.name)
target_file = self.remote_file.get_child_for_display_name(remote_filename)
- self.copy_file(source_file, target_file)
+ self.copy_file('put', source_file, target_file)
def get(self, filename, local_path):
"""Get file and put in local_path (Path object)"""
source_file = self.remote_file.get_child_for_display_name(filename)
target_file = gio.File(path=local_path.name)
- self.copy_file(source_file, target_file)
+ self.copy_file('get', source_file, target_file)
local_path.setdata()
def list(self):
"""List files in that directory"""
- enum = self.remote_file.enumerate_children(gio.FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME,
- gio.FILE_QUERY_INFO_NOFOLLOW_SYMLINKS)
+ try:
+ enum = self.remote_file.enumerate_children(gio.FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME,
+ gio.FILE_QUERY_INFO_NOFOLLOW_SYMLINKS)
+ except Exception, e:
+ self.handle_error(e, 'list', self.remote_file.get_parse_name())
files = []
try:
info = enum.next_file()
@@ -133,7 +151,7 @@
info = enum.next_file()
return files
except Exception, e:
- raise BackendException(str(e))
+ self.handle_error(e, 'list')
def delete(self, filename_list):
"""Delete all files in filename list"""
@@ -142,4 +160,4 @@
for filename in filename_list:
self.remote_file.get_child_for_display_name(filename).delete()
except Exception, e:
- raise BackendException(str(e))
+ self.handle_error(e, 'delete', self.remote_file.get_child_for_display_name(filename).get_parse_name())
=== modified file 'duplicity/backends/localbackend.py'
--- duplicity/backends/localbackend.py 2010-11-20 15:39:00 +0000
+++ duplicity/backends/localbackend.py 2010-12-04 22:17:53 +0000
@@ -21,10 +21,12 @@
import os
import types
+import errno
import duplicity.backend
from duplicity import log
from duplicity import path
+from duplicity import util
from duplicity.errors import * #@UnusedWildImport
class LocalBackend(duplicity.backend.Backend):
@@ -41,6 +43,19 @@
raise BackendException( "Bad file:// path syntax." )
self.remote_pathdir = path.Path(parsed_url.path[2:])
+ def handle_error(self, e, op, file1=None, file2=None):
+ code = log.ErrorCode.backend_error
+ if hasattr(e, 'errno'):
+ if e.errno == errno.EACCES:
+ code = log.ErrorCode.backend_permission_denied
+ elif e.errno == errno.ENOENT:
+ code = log.ErrorCode.backend_not_found
+ elif e.errno == errno.ENOSPC:
+ code = log.ErrorCode.backend_no_space
+ extra = ' '.join([util.escape(x) for x in [file1, file2] if x])
+ extra = ' '.join([op, extra])
+ log.FatalError(str(e), code, extra)
+
def put(self, source_path, remote_filename = None, rename = None):
"""If rename is set, try that first, copying if doesn't work"""
if not remote_filename:
@@ -52,14 +67,22 @@
source_path.rename(target_path)
except OSError:
pass
+ except Exception, e:
+ handle_error(e, 'put', source_path.name, target_path.name)
else:
return
- target_path.writefileobj(source_path.open("rb"))
+ try:
+ target_path.writefileobj(source_path.open("rb"))
+ except Exception, e:
+ self.handle_error(e, 'put', source_path.name, target_path.name)
def get(self, filename, local_path):
"""Get file and put in local_path (Path object)"""
source_path = self.remote_pathdir.append(filename)
- local_path.writefileobj(source_path.open("rb"))
+ try:
+ local_path.writefileobj(source_path.open("rb"))
+ except Exception, e:
+ self.handle_error(e, 'get', source_path.name, local_path.name)
def list(self):
"""List files in that directory"""
@@ -67,7 +90,10 @@
os.makedirs(self.remote_pathdir.base)
except:
pass
- return self.remote_pathdir.listdir()
+ try:
+ return self.remote_pathdir.listdir()
+ except Exception, e:
+ self.handle_error(e, 'list', self.remote_pathdir.name)
def delete(self, filename_list):
"""Delete all files in filename list"""
@@ -75,8 +101,8 @@
for filename in filename_list:
try:
self.remote_pathdir.append(filename).delete()
- except OSError, e:
- raise BackendException(str(e))
+ except Exception, e:
+ self.handle_error(e, 'delete', self.remote_pathdir.append(filename).name)
duplicity.backend.register_backend("file", LocalBackend)
=== modified file 'duplicity/log.py'
--- duplicity/log.py 2010-11-20 15:39:00 +0000
+++ duplicity/log.py 2010-12-04 22:17:53 +0000
@@ -179,6 +179,13 @@
restart_file_not_found = 39
gio_not_available = 40
source_dir_mismatch = 42 # 41 is reserved for par2
+
+ # 50->69 reserved for backend errors
+ backend_error = 50
+ backend_permission_denied = 51
+ backend_not_found = 52
+ backend_no_space = 53
+
# Reserve 255 because it is used as an error code for gksu
def FatalError(s, code, extra=None):
Follow ups