Skip to content

Commit 764efd3

Browse files
whymp12tic
authored andcommitted
Hide stack trace shown on YAML parse error by default
Fixes #1139 Signed-off-by: Yusuke Matsubara <whym@whym.org>
1 parent b062243 commit 764efd3

File tree

5 files changed

+87
-3
lines changed

5 files changed

+87
-3
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Hide the stack trace on a YAML parse error.

podman_compose.py

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1904,6 +1904,15 @@ def rec_merge(target: dict[str, Any], *sources: dict[str, Any]) -> dict[str, Any
19041904
return ret
19051905

19061906

1907+
def load_yaml_or_die(file_path: str, stream: Any) -> dict[str, Any]:
1908+
try:
1909+
return yaml.safe_load(stream)
1910+
except yaml.scanner.ScannerError as e:
1911+
log.fatal("Compose file contains an error:\n%s", e)
1912+
log.info("Compose file %s contains an error:", file_path, exc_info=e)
1913+
sys.exit(1)
1914+
1915+
19071916
def resolve_extends(
19081917
services: dict[str, Any], service_names: list[str], environ: dict[str, Any]
19091918
) -> None:
@@ -1920,7 +1929,7 @@ def resolve_extends(
19201929
if filename.startswith("./"):
19211930
filename = filename[2:]
19221931
with open(filename, "r", encoding="utf-8") as f:
1923-
content = yaml.safe_load(f) or {}
1932+
content = load_yaml_or_die(filename, f) or {}
19241933
if "services" in content:
19251934
content = content["services"]
19261935
subdirectory = os.path.dirname(filename)
@@ -2229,10 +2238,10 @@ def _parse_compose_file(self) -> None:
22292238
break
22302239

22312240
if filename.strip().split('/')[-1] == '-':
2232-
content = yaml.safe_load(sys.stdin)
2241+
content = load_yaml_or_die(filename, sys.stdin)
22332242
else:
22342243
with open(filename, "r", encoding="utf-8") as f:
2235-
content = yaml.safe_load(f)
2244+
content = load_yaml_or_die(filename, f)
22362245
# log(filename, json.dumps(content, indent = 2))
22372246
if not isinstance(content, dict):
22382247
sys.stderr.write(
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
version: "3"
2+
services:foo
3+
web1:
4+
image: busybox
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
version: "3"
2+
services:
3+
web1:
4+
image: busybox
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
# SPDX-License-Identifier: GPL-2.0
2+
3+
import os
4+
import unittest
5+
6+
from tests.integration.test_utils import RunSubprocessMixin
7+
from tests.integration.test_utils import podman_compose_path
8+
from tests.integration.test_utils import test_path
9+
10+
11+
def bad_compose_yaml_path() -> str:
12+
base_path = os.path.join(test_path(), "parse-error")
13+
return os.path.join(base_path, "docker-compose-error.yml")
14+
15+
16+
def good_compose_yaml_path() -> str:
17+
base_path = os.path.join(test_path(), "parse-error")
18+
return os.path.join(base_path, "docker-compose.yml")
19+
20+
21+
class TestComposeBuildParseError(unittest.TestCase, RunSubprocessMixin):
22+
def test_no_error(self) -> None:
23+
try:
24+
_, err = self.run_subprocess_assert_returncode(
25+
[podman_compose_path(), "-f", good_compose_yaml_path(), "config"], 0
26+
)
27+
self.assertEqual(b"", err)
28+
29+
finally:
30+
self.run_subprocess([
31+
podman_compose_path(),
32+
"-f",
33+
bad_compose_yaml_path(),
34+
"down",
35+
])
36+
37+
def test_simple_parse_error(self) -> None:
38+
try:
39+
_, err = self.run_subprocess_assert_returncode(
40+
[podman_compose_path(), "-f", bad_compose_yaml_path(), "config"], 1
41+
)
42+
self.assertIn(b"could not find expected ':'", err)
43+
self.assertNotIn(b"\nTraceback (most recent call last):\n", err)
44+
45+
finally:
46+
self.run_subprocess([
47+
podman_compose_path(),
48+
"-f",
49+
bad_compose_yaml_path(),
50+
"down",
51+
])
52+
53+
def test_verbose_parse_error_contains_stack_trace(self) -> None:
54+
try:
55+
_, err = self.run_subprocess_assert_returncode(
56+
[podman_compose_path(), "--verbose", "-f", bad_compose_yaml_path(), "config"], 1
57+
)
58+
self.assertIn(b"\nTraceback (most recent call last):\n", err)
59+
60+
finally:
61+
self.run_subprocess([
62+
podman_compose_path(),
63+
"-f",
64+
bad_compose_yaml_path(),
65+
"down",
66+
])

0 commit comments

Comments
 (0)