mirror of
https://github.com/samsonjs/vdirsyncer.git
synced 2026-03-25 08:55:50 +00:00
Move "obscure" exceptions into their own modules
This commit is contained in:
parent
233e8524ab
commit
9616f0bbfe
5 changed files with 36 additions and 38 deletions
|
|
@ -240,7 +240,7 @@ class TestCaldavStorage(DavStorageTests):
|
|||
|
||||
monkeypatch.setattr('requests.sessions.Session.request', request)
|
||||
|
||||
with pytest.raises(exceptions.StorageError):
|
||||
with pytest.raises(ValueError):
|
||||
self.storage_class(**args)
|
||||
assert len(calls) == 1
|
||||
|
||||
|
|
|
|||
|
|
@ -10,10 +10,9 @@
|
|||
import pytest
|
||||
|
||||
from . import assert_item_equals, normalize_item
|
||||
import vdirsyncer.exceptions as exceptions
|
||||
from vdirsyncer.storage.base import Item
|
||||
from vdirsyncer.storage.memory import MemoryStorage
|
||||
from vdirsyncer.sync import sync
|
||||
from vdirsyncer.sync import sync, SyncConflict, StorageEmpty
|
||||
|
||||
|
||||
def empty_storage(x):
|
||||
|
|
@ -51,7 +50,7 @@ def test_missing_status_and_different_items():
|
|||
item2 = Item(u'UID:1\nhoho')
|
||||
a.upload(item1)
|
||||
b.upload(item2)
|
||||
with pytest.raises(exceptions.SyncConflict):
|
||||
with pytest.raises(SyncConflict):
|
||||
sync(a, b, status)
|
||||
assert not status
|
||||
sync(a, b, status, conflict_resolution='a wins')
|
||||
|
|
@ -137,7 +136,7 @@ def test_conflict_resolution_both_etags_new(winning_storage):
|
|||
assert status
|
||||
a.update(href_a, Item(u'UID:1\nitem a'), etag_a)
|
||||
b.update(href_b, Item(u'UID:1\nitem b'), etag_b)
|
||||
with pytest.raises(exceptions.SyncConflict):
|
||||
with pytest.raises(SyncConflict):
|
||||
sync(a, b, status)
|
||||
sync(a, b, status, conflict_resolution='{} wins'.format(winning_storage))
|
||||
item_a, _ = a.get(href_a)
|
||||
|
|
@ -203,8 +202,8 @@ def test_empty_storage_dataloss():
|
|||
a.upload(Item(u'UID:2'))
|
||||
status = {}
|
||||
sync(a, b, status)
|
||||
with pytest.raises(exceptions.StorageEmpty):
|
||||
with pytest.raises(StorageEmpty):
|
||||
sync(MemoryStorage(), b, status)
|
||||
|
||||
with pytest.raises(exceptions.StorageEmpty):
|
||||
with pytest.raises(StorageEmpty):
|
||||
sync(a, MemoryStorage(), status)
|
||||
|
|
|
|||
|
|
@ -3,6 +3,9 @@
|
|||
vdirsyncer.exceptions
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Contains exception classes used by vdirsyncer. Not all exceptions are here,
|
||||
only the most commonly used ones.
|
||||
|
||||
:copyright: (c) 2014 Markus Unterwaditzer
|
||||
:license: MIT, see LICENSE for more details.
|
||||
'''
|
||||
|
|
@ -33,29 +36,3 @@ class AlreadyExistingError(PreconditionFailed):
|
|||
|
||||
class WrongEtagError(PreconditionFailed):
|
||||
'''Wrong etag'''
|
||||
|
||||
|
||||
class StorageError(Error):
|
||||
'''Internal or initialization errors with storage.'''
|
||||
|
||||
|
||||
class SyncError(Error):
|
||||
'''Errors related to synchronization.'''
|
||||
|
||||
|
||||
class SyncConflict(SyncError):
|
||||
'''
|
||||
Two items changed since the last sync, they now have different contents and
|
||||
no conflict resolution method was given.
|
||||
'''
|
||||
|
||||
|
||||
class StorageEmpty(SyncError):
|
||||
'''
|
||||
One storage unexpectedly got completely empty between two synchronizations.
|
||||
The first argument is the empty storage.
|
||||
'''
|
||||
|
||||
@property
|
||||
def empty_storage(self):
|
||||
return self.args[0]
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ class DavStorage(Storage):
|
|||
)
|
||||
response.raise_for_status()
|
||||
if self.dav_header not in response.headers.get('DAV', ''):
|
||||
raise exceptions.StorageError('URL is not a collection')
|
||||
raise ValueError('URL is not a collection')
|
||||
|
||||
def _default_headers(self):
|
||||
return {
|
||||
|
|
|
|||
|
|
@ -22,6 +22,28 @@ from .utils import iteritems, itervalues
|
|||
sync_logger = log.get(__name__)
|
||||
|
||||
|
||||
class SyncError(exceptions.Error):
|
||||
'''Errors related to synchronization.'''
|
||||
|
||||
|
||||
class SyncConflict(SyncError):
|
||||
'''
|
||||
Two items changed since the last sync, they now have different contents and
|
||||
no conflict resolution method was given.
|
||||
'''
|
||||
|
||||
|
||||
class StorageEmpty(SyncError):
|
||||
'''
|
||||
One storage unexpectedly got completely empty between two synchronizations.
|
||||
The first argument is the empty storage.
|
||||
'''
|
||||
|
||||
@property
|
||||
def empty_storage(self):
|
||||
return self.args[0]
|
||||
|
||||
|
||||
def prepare_list(storage, href_to_status):
|
||||
download = []
|
||||
for href, etag in storage.list():
|
||||
|
|
@ -55,9 +77,9 @@ def sync(storage_a, storage_b, status, conflict_resolution=None,
|
|||
If this is the first sync, an empty dictionary should be provided.
|
||||
:param conflict_resolution: Either 'a wins' or 'b wins'. If none is
|
||||
provided, the sync function will raise
|
||||
:py:exc:`vdirsyncer.exceptions.SyncConflict`.
|
||||
:py:exc:`SyncConflict`.
|
||||
:param force_delete: When one storage got completely emptied between two
|
||||
syncs, :py:exc:`vdirsyncer.exceptions.StorageEmpty` is raised for
|
||||
syncs, :py:exc:`StorageEmpty` is raised for
|
||||
safety. Setting this parameter to ``True`` disables this safety
|
||||
measure.
|
||||
'''
|
||||
|
|
@ -74,7 +96,7 @@ def sync(storage_a, storage_b, status, conflict_resolution=None,
|
|||
list_b = dict(prepare_list(storage_b, b_href_to_status))
|
||||
|
||||
if bool(list_a) != bool(list_b) and status and not force_delete:
|
||||
raise exceptions.StorageEmpty(storage_b if list_a else storage_a)
|
||||
raise StorageEmpty(storage_b if list_a else storage_a)
|
||||
|
||||
a_uid_to_href = dict((x['uid'], href) for href, x in iteritems(list_a))
|
||||
b_uid_to_href = dict((x['uid'], href) for href, x in iteritems(list_b))
|
||||
|
|
@ -165,7 +187,7 @@ def action_conflict_resolve(uid):
|
|||
sync_logger.info('...same content on both sides.')
|
||||
status[uid] = a_href, a_meta['etag'], b_href, b_meta['etag']
|
||||
elif conflict_resolution is None:
|
||||
raise exceptions.SyncConflict()
|
||||
raise SyncConflict()
|
||||
elif conflict_resolution == 'a wins':
|
||||
sync_logger.info('...{} wins.'.format(a_storage))
|
||||
action_update(uid, 'a', 'b')(storages, status, conflict_resolution)
|
||||
|
|
|
|||
Loading…
Reference in a new issue