Skip to content

Commit e23cb90

Browse files
authored
Merge pull request #129 from JulienPalard/show-context
On validation error: add cause and context.
2 parents afb6024 + 2dcf445 commit e23cb90

File tree

3 files changed

+76
-1
lines changed

3 files changed

+76
-1
lines changed

openapi_spec_validator/__main__.py

+31-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
import argparse
33
import sys
44

5+
from jsonschema.exceptions import best_match
6+
57
from openapi_spec_validator import (
68
openapi_v2_spec_validator, openapi_v3_spec_validator,
79
)
@@ -15,9 +17,37 @@
1517
)
1618

1719

20+
def print_validationerror(exc, errors="best-match"):
21+
print("# Validation Error\n")
22+
print(exc)
23+
if exc.cause:
24+
print("\n# Cause\n")
25+
print(exc.cause)
26+
if not exc.context:
27+
return
28+
if errors == "all":
29+
print("\n\n# Due to one of those errors\n")
30+
print("\n\n\n".join("## " + str(e) for e in exc.context))
31+
elif errors == "best-match":
32+
print("\n\n# Probably due to this subschema error\n")
33+
print("## " + str(best_match(exc.context)))
34+
if len(exc.context) > 1:
35+
print(
36+
"\n({} more subschemas errors,".format(len(exc.context) - 1),
37+
"use --errors=all to see them.)",
38+
)
39+
40+
1841
def main(args=None):
1942
parser = argparse.ArgumentParser()
2043
parser.add_argument('filename', help="Absolute or relative path to file")
44+
parser.add_argument(
45+
"--errors",
46+
choices=("best-match", "all"),
47+
default="best-match",
48+
help="""Control error reporting. Defaults to "best-match", """
49+
"""use "all" to get all subschema errors.""",
50+
)
2151
parser.add_argument(
2252
'--schema',
2353
help="OpenAPI schema (default: 3.0.0)",
@@ -50,7 +80,7 @@ def main(args=None):
5080
try:
5181
validator.validate(spec, spec_url=spec_url)
5282
except ValidationError as exc:
53-
print(exc)
83+
print_validationerror(exc, args.errors)
5484
sys.exit(1)
5585
except Exception as exc:
5686
print(exc)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
---
2+
openapi: 3.0.0
3+
4+
info:
5+
title: test
6+
description: test
7+
version: 0.0.1
8+
9+
paths:
10+
"/":
11+
get:
12+
description: Get the API root
13+
responses:
14+
200:
15+
content:
16+
application/json:
17+
schema:
18+
type: string

tests/integration/test_main.py

+27
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,33 @@ def test_schema_v2():
2626
main(testargs)
2727

2828

29+
def test_errors_on_missing_description_best(capsys):
30+
"""An error is obviously printed given an empty schema."""
31+
testargs = ['./tests/integration/data/v3.0/missing-description.yaml']
32+
with pytest.raises(SystemExit):
33+
main(testargs)
34+
out, err = capsys.readouterr()
35+
assert "Failed validating" in out
36+
assert "'description' is a required property" in out
37+
assert "'$ref' is a required property" not in out
38+
assert '1 more subschemas errors' in out
39+
40+
41+
def test_errors_on_missing_description_full(capsys):
42+
"""An error is obviously printed given an empty schema."""
43+
testargs = [
44+
"./tests/integration/data/v3.0/missing-description.yaml",
45+
"--errors=all"
46+
]
47+
with pytest.raises(SystemExit):
48+
main(testargs)
49+
out, err = capsys.readouterr()
50+
assert "Failed validating" in out
51+
assert "'description' is a required property" in out
52+
assert "'$ref' is a required property" in out
53+
assert '1 more subschema error' not in out
54+
55+
2956
def test_schema_unknown():
3057
"""Errors on running with unknown schema."""
3158
testargs = ['--schema', 'x.x',

0 commit comments

Comments
 (0)