Browse Source

When command-line configuration override produces a parse error, error cleanly (#471).

Dan Helfman 3 years ago
parent
commit
0e8e9ced64
3 changed files with 17 additions and 1 deletions
  1. 2 0
      NEWS
  2. 5 1
      borgmatic/config/override.py
  3. 10 0
      tests/unit/config/test_override.py

+ 2 - 0
NEWS

@@ -1,5 +1,7 @@
 1.5.22.dev0
  * #470: Move mysqldump options to the beginning of the command due to MySQL bug 30994.
+ * #471: When command-line configuration override produces a parse error, error cleanly instead of
+   tracebacking.
 
 1.5.21
  * #28: Optionally retry failing backups via "retries" and "retry_wait" configuration options.

+ 5 - 1
borgmatic/config/override.py

@@ -26,6 +26,8 @@ def convert_value_type(value):
     '''
     Given a string value, determine its logical type (string, boolean, integer, etc.), and return it
     converted to that type.
+
+    Raise ruamel.yaml.error.YAMLError if there's a parse issue with the YAML.
     '''
     return ruamel.yaml.YAML(typ='safe').load(io.StringIO(value))
 
@@ -57,7 +59,9 @@ def parse_overrides(raw_overrides):
             for raw_keys, value in (raw_override.split('=', 1),)
         )
     except ValueError:
-        raise ValueError('Invalid override. Make sure you use the form: SECTION.OPTION=VALUE')
+        raise ValueError(f'Invalid override. Make sure you use the form: SECTION.OPTION=VALUE')
+    except ruamel.yaml.error.YAMLError as error:
+        raise ValueError(f'Invalid override value: {error}')
 
 
 def apply_overrides(config, raw_overrides):

+ 10 - 0
tests/unit/config/test_override.py

@@ -1,6 +1,8 @@
 import pytest
 from flexmock import flexmock
 
+import ruamel.yaml
+
 from borgmatic.config import override as module
 
 
@@ -70,6 +72,14 @@ def test_parse_overrides_raises_on_missing_equal_sign():
         module.parse_overrides(raw_overrides)
 
 
+def test_parse_overrides_raises_on_invalid_override_value():
+    flexmock(module).should_receive('convert_value_type').and_raise(ruamel.yaml.parser.ParserError)
+    raw_overrides = ['section.option=[in valid]']
+
+    with pytest.raises(ValueError):
+        module.parse_overrides(raw_overrides)
+
+
 def test_parse_overrides_allows_value_with_single_key():
     flexmock(module).should_receive('convert_value_type').replace_with(lambda value: value)
     raw_overrides = ['option=value']