Skip to content

Commit c7351a6

Browse files
committed
feat: add new properties to ValidationError
ValidationError had a single untyped property: .data, which hold different objects in the XML and JSON cases, while they do have some common properties. The new properties introduced in this commit are - .message: the error message text - .path: pointer to the location of the error in the input Signed-off-by: Krisztian Fekete <[email protected]>
1 parent e23446b commit c7351a6

File tree

4 files changed

+34
-4
lines changed

4 files changed

+34
-4
lines changed

cyclonedx/validation/__init__.py

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,26 @@
3030
class ValidationError:
3131
"""Validation failed with this specific error.
3232
33-
Use :attr:`~data` to access the content.
33+
You can use :attr:`~data` to access the raw error object, but prefer
34+
other properties and functions, if possible.
3435
"""
3536

3637
data: Any
38+
"""Raw error data from one of the validation libraries."""
39+
40+
@property
41+
def message(self) -> str:
42+
"""The error message."""
43+
return str(getattr(self.data, 'message', self))
44+
45+
@property
46+
def path(self) -> str:
47+
"""Path to the location of the problem in the document.
48+
49+
An XPath/JSONPath string.
50+
"""
51+
# only subclasses know how to extract this info
52+
return str(getattr(self.data, 'path', ''))
3753

3854
def __init__(self, data: Any) -> None:
3955
self.data = data

cyclonedx/validation/json.py

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333

3434
_missing_deps_error: Optional[tuple[MissingOptionalDependencyException, ImportError]] = None
3535
try:
36-
from jsonschema.exceptions import ValidationError as JsonValidationError # type:ignore[import-untyped]
36+
from jsonschema.exceptions import ValidationError as JsonSchemaValidationError # type:ignore[import-untyped]
3737
from jsonschema.validators import Draft7Validator # type:ignore[import-untyped]
3838
from referencing import Registry
3939
from referencing.jsonschema import DRAFT7
@@ -47,6 +47,16 @@
4747
), err
4848

4949

50+
class _JsonValidationError(ValidationError):
51+
@property
52+
def path(self) -> str:
53+
"""Path to the location of the problem in the document.
54+
55+
An XPath/JSONPath string.
56+
"""
57+
return str(getattr(self.data, 'json_path', ''))
58+
59+
5060
class _BaseJsonValidator(BaseSchemabasedValidator, ABC):
5161
@property
5262
def output_format(self) -> Literal[OutputFormat.JSON]:
@@ -71,8 +81,8 @@ def _validate_data(self, data: Any) -> Optional[ValidationError]:
7181
validator = self._validator # may throw on error that MUST NOT be caught
7282
try:
7383
validator.validate(data)
74-
except JsonValidationError as error:
75-
return ValidationError(error)
84+
except JsonSchemaValidationError as error:
85+
return _JsonValidationError(error)
7686
return None
7787

7888
__validator: Optional['JsonSchemaValidator'] = None

tests/test_validation_json.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,3 +132,5 @@ def test_validate_expected_error(self, schema_version: SchemaVersion, test_data_
132132
self.skipTest('MissingOptionalDependencyException')
133133
self.assertIsNotNone(validation_error)
134134
self.assertIsNotNone(validation_error.data)
135+
self.assertTrue(bool(validation_error.message))
136+
self.assertTrue(bool(validation_error.path))

tests/test_validation_xml.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,3 +92,5 @@ def test_validate_expected_error(self, schema_version: SchemaVersion, test_data_
9292
self.skipTest('MissingOptionalDependencyException')
9393
self.assertIsNotNone(validation_error)
9494
self.assertIsNotNone(validation_error.data)
95+
self.assertTrue(bool(validation_error.message))
96+
self.assertTrue(bool(validation_error.path))

0 commit comments

Comments
 (0)