From ca503838e69771d38cc4ed03bb23bf188cdde7a1 Mon Sep 17 00:00:00 2001 From: Allen Porter Date: Sat, 29 Jun 2024 12:09:43 -0700 Subject: [PATCH] Improve error messages for parse failures (#732) Improve command output for cases like parsing helm values that contain invalid values. #731 --- flux_local/kustomize.py | 7 ++++++- tests/test_kustomize.py | 27 ++++++++++++++++++++++++--- 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/flux_local/kustomize.py b/flux_local/kustomize.py index f3fba196..5ae9948e 100644 --- a/flux_local/kustomize.py +++ b/flux_local/kustomize.py @@ -127,7 +127,12 @@ async def objects( self, target_namespace: str | None = None ) -> list[dict[str, Any]]: """Run the kustomize command and return the result cluster objects as a list.""" - return [doc async for doc in self._docs(target_namespace=target_namespace)] + try: + return [doc async for doc in self._docs(target_namespace=target_namespace)] + except yaml.YAMLError as err: + raise KustomizeException( + f"Unable to parse command output: {self._cmds}: {err}" + ) from err def skip_resources(self, kinds: list[str]) -> "Kustomize": """Skip resources kinds of the specified types.""" diff --git a/tests/test_kustomize.py b/tests/test_kustomize.py index 1efb06e0..5e38323d 100644 --- a/tests/test_kustomize.py +++ b/tests/test_kustomize.py @@ -6,7 +6,7 @@ from syrupy.assertion import SnapshotAssertion import yaml -from flux_local import kustomize, exceptions, manifest +from flux_local import kustomize, exceptions, manifest, command TESTDATA_DIR = Path("tests/testdata") @@ -44,6 +44,28 @@ async def test_objects(path: Path, snapshot: SnapshotAssertion) -> None: assert result == snapshot +INVALID_YAML = """ +--- +foo: !bar +""" + + +async def test_objects_failure() -> None: + """Test loading yaml documents.""" + + class FakeTask(command.Task): + async def run(self, stdin: bytes | None = None) -> bytes: + """Execute the task and return the result.""" + return INVALID_YAML.encode() + + cmd = kustomize.Kustomize([FakeTask()]) + with pytest.raises( + exceptions.KustomizeException, + match=r"Unable to parse.*could not determine a constructor", + ): + await cmd.objects() + + @pytest.mark.parametrize( "path", [TESTDATA_DIR / "repo", (TESTDATA_DIR / "repo").absolute()], @@ -80,8 +102,7 @@ async def test_validate_pass(path: Path) -> None: async def test_validate_fail(path: Path) -> None: """Test applying policies to validate resources.""" cmd = kustomize.grep("kind=ConfigMap", path) - with pytest.raises( - exceptions.CommandException, match="fail: 1"): + with pytest.raises(exceptions.CommandException, match="fail: 1"): await cmd.validate(TESTDATA_DIR / "policies/fail.yaml")