diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 13cb763..3bb2f47 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -9,6 +9,12 @@ Package maintainers and users who have to manually update their installation may want to subscribe to `GitHub's tag feed `_. +Version 0.14.0 +============== + +- ``vdirsyncer sync`` now continues other uploads if one upload failed. The + exit code in such situations is still non-zero. + Version 0.13.1 ============== diff --git a/vdirsyncer/cli/tasks.py b/vdirsyncer/cli/tasks.py index b0236f5..ce62149 100644 --- a/vdirsyncer/cli/tasks.py +++ b/vdirsyncer/cli/tasks.py @@ -56,18 +56,33 @@ def sync_collection(wq, collection, general, force_delete): a = storage_instance_from_config(collection.config_a) b = storage_instance_from_config(collection.config_b) + + sync_failed = False + + def error_callback(e): + nonlocal sync_failed + sync_failed = True + handle_cli_error(status_name, e) + sync( a, b, status, conflict_resolution=pair.conflict_resolution, - force_delete=force_delete + force_delete=force_delete, + error_callback=error_callback + ) + + save_status(general['status_path'], pair.name, collection.name, + data_type='items', data=status) + + if sync_failed: + raise JobFailed() + except JobFailed: + raise except BaseException: handle_cli_error(status_name) raise JobFailed() - save_status(general['status_path'], pair.name, collection.name, - data_type='items', data=status) - def discover_collections(wq, pair, **kwargs): rv = collections_for_pair(pair=pair, **kwargs) diff --git a/vdirsyncer/cli/utils.py b/vdirsyncer/cli/utils.py index 823af16..0104a23 100644 --- a/vdirsyncer/cli/utils.py +++ b/vdirsyncer/cli/utils.py @@ -71,7 +71,7 @@ class JobFailed(RuntimeError): # TODO: Making this a decorator would be nice -def handle_cli_error(status_name=None): +def handle_cli_error(status_name=None, e=None): ''' Print a useful error message for the current exception. @@ -80,7 +80,10 @@ def handle_cli_error(status_name=None): ''' try: - raise + if e is not None: + raise e + else: + raise except exceptions.UserError as e: cli_logger.critical(e) except StorageEmpty as e: