Skip to content

Commit c1f2c6c

Browse files
committed
Improve diagnostic message when failing to load yaml files
Detected while debugging extension diagnostic messages as we spotted undesired slipping of line/column information inside of the generated error message. Related: ansible/vscode-ansible#2005
1 parent 581df99 commit c1f2c6c

File tree

6 files changed

+48
-7
lines changed

6 files changed

+48
-7
lines changed

examples/load-failure-invalid.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
- aaa: 1
3+
bbb: 2
4+
c: 3
5+
foo: bar

src/ansiblelint/runner.py

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@
4444
parse_examples_from_plugin,
4545
template,
4646
)
47+
from yaml.scanner import ScannerError
48+
from ruamel.yaml.parser import ParserError as RuamelParserError
49+
from yaml.parser import ParserError
4750

4851
if TYPE_CHECKING:
4952
from collections.abc import Callable, Generator
@@ -213,14 +216,30 @@ def _run(self) -> list[MatchError]:
213216
self.lintables.remove(lintable)
214217
continue
215218
if isinstance(lintable.data, States) and lintable.exc:
219+
line = 1
220+
column = None
221+
detail = ""
222+
sub_tag = ""
216223
lintable.exc.__class__.__name__.lower()
224+
message = None
225+
if lintable.exc.__cause__ and isinstance(lintable.exc.__cause__, ScannerError | ParserError | RuamelParserError):
226+
sub_tag = "yaml"
227+
if isinstance(lintable.exc.args, tuple):
228+
message = lintable.exc.args[0]
229+
detail = lintable.exc.__cause__.problem
230+
if lintable.exc.__cause__.problem_mark:
231+
line = lintable.exc.__cause__.problem_mark.line + 1
232+
column = lintable.exc.__cause__.problem_mark.column + 1
233+
217234
matches.append(
218235
MatchError(
219236
lintable=lintable,
220-
message=str(lintable.exc),
221-
details=str(lintable.exc.__cause__),
237+
message=message or str(lintable.exc),
238+
details=detail or str(lintable.exc.__cause__),
222239
rule=self.rules["load-failure"],
223-
tag=f"load-failure[{lintable.exc.__class__.__name__.lower()}]",
240+
lineno=line,
241+
column=column,
242+
tag=f"load-failure[{sub_tag or lintable.exc.__class__.__name__.lower()}]",
224243
),
225244
)
226245
lintable.stop_processing = True

src/ansiblelint/schemas/__store__.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
"url": "https://raw.githubusercontent.com/ansible/ansible-lint/main/src/ansiblelint/schemas/inventory.json"
2525
},
2626
"meta": {
27-
"etag": "ba724ad96ccb630237b908377c31796a1208265731b4b8a8fa91ffb7e52c611b",
27+
"etag": "50a33e03b769d4574f20f192ce37dcb694361a8b30e030b2c1274f393e6595e4",
2828
"url": "https://raw.githubusercontent.com/ansible/ansible-lint/main/src/ansiblelint/schemas/meta.json"
2929
},
3030
"meta-runtime": {

src/ansiblelint/utils.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1160,8 +1160,8 @@ def construct_mapping(
11601160
yaml.constructor.ConstructorError,
11611161
ruamel.yaml.parser.ParserError,
11621162
) as exc:
1163-
msg = f"Failed to load YAML file: {lintable.path}"
1164-
raise RuntimeError(msg) from exc
1163+
msg = "Failed to load YAML file"
1164+
raise RuntimeError(msg, lintable.path) from exc
11651165

11661166
if len(result) == 0:
11671167
return None # empty documents

test/test_runner.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,23 @@ def test_runner_not_found(default_rules_collection: RulesCollection) -> None:
240240
assert len(result) == 1
241241
assert result[0].tag == "load-failure[not-found]"
242242

243+
def test_runner_load_failure_yaml(default_rules_collection: RulesCollection) -> None:
244+
"""Ensure load-failure[yaml] work as expected."""
245+
checked_files: set[Lintable] = set()
246+
247+
filename = Path("examples/load-failure-invalid.yml").resolve()
248+
runner = Runner(
249+
filename,
250+
rules=default_rules_collection,
251+
verbosity=0,
252+
checked_files=checked_files,
253+
)
254+
result = runner.run()
255+
assert len(runner.checked_files) == 1
256+
assert len(result) == 1
257+
assert result[0].tag == "load-failure[yaml]"
258+
assert result[0].lineno == 5
259+
assert result[0].column == 1
243260

244261
def test_runner_tmp_file(
245262
tmp_path: Path,

tox.ini

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ set_env =
5656
PIP_CONSTRAINT = {tox_root}/.config/constraints.txt
5757
PIP_DISABLE_PIP_VERSION_CHECK = 1
5858
PRE_COMMIT_COLOR = always
59-
PYTEST_REQPASS = 908
59+
PYTEST_REQPASS = 909
6060
UV_CONSTRAINT = {tox_root}/.config/constraints.txt
6161
deps, devel, hook, lint, pkg, pre, py310, schemas: PIP_CONSTRAINT = /dev/null
6262
deps, devel, hook, lint, pkg, pre, py310, schemas: UV_CONSTRAINT = /dev/null

0 commit comments

Comments
 (0)