diff --git a/tests/cli/test_main.py b/tests/cli/test_main.py index 23d5895..bb89c76 100644 --- a/tests/cli/test_main.py +++ b/tests/cli/test_main.py @@ -44,6 +44,13 @@ def test_simple_run(tmpdir, runner): assert tmpdir.join('path_b/haha.txt').read() == 'UID:haha' +def test_sync_inexistant_pair(tmpdir, runner): + runner.write_with_general("") + result = runner.invoke(['sync', 'foo']) + assert result.exception + assert 'pair foo does not exist.' in result.output.lower() + + def test_debug_connections(tmpdir, runner): runner.write_with_general(dedent(''' [pair my_pair] diff --git a/vdirsyncer/cli/config.py b/vdirsyncer/cli/config.py index 7f493d1..e663973 100644 --- a/vdirsyncer/cli/config.py +++ b/vdirsyncer/cli/config.py @@ -217,7 +217,10 @@ class Config(object): return expand_fetch_params(args) def get_pair(self, pair_name): - return PairConfig(self, pair_name, *self.pairs[pair_name]) + try: + return PairConfig(self, pair_name, *self.pairs[pair_name]) + except KeyError as e: + raise exceptions.PairNotFound(e, pair_name=pair_name) class PairConfig(object): diff --git a/vdirsyncer/cli/utils.py b/vdirsyncer/cli/utils.py index f54fec3..3ea3ec4 100644 --- a/vdirsyncer/cli/utils.py +++ b/vdirsyncer/cli/utils.py @@ -68,6 +68,7 @@ class JobFailed(RuntimeError): pass +# TODO: Making this a decorator would be nice def handle_cli_error(status_name=None): ''' Print a useful error message for the current exception. @@ -118,6 +119,12 @@ def handle_cli_error(status_name=None): ) except (click.Abort, KeyboardInterrupt, JobFailed): pass + except exceptions.PairNotFound as e: + cli_logger.error( + 'Pair {pair_name} does not exist. Please check your ' + 'configuration file and make sure you\'ve typed the pair name ' + 'correctly'.format(pair_name=e.pair_name) + ) except Exception as e: if status_name: msg = 'Unhandled exception occured for {}.'.format( diff --git a/vdirsyncer/exceptions.py b/vdirsyncer/exceptions.py index 1a58816..888cb71 100644 --- a/vdirsyncer/exceptions.py +++ b/vdirsyncer/exceptions.py @@ -35,6 +35,12 @@ class CollectionNotFound(Error): '''Collection not found''' +class PairNotFound(Error): + '''Pair not found''' + + pair_name = None + + class PreconditionFailed(Error): ''' - The item doesn't exist although it should