feat: alters all standart errors and messages for more specific errors
This commit is contained in:
@@ -1,3 +1,4 @@
|
|||||||
|
from jambo.exceptions import InvalidSchemaException
|
||||||
from jambo.parser._type_parser import GenericTypeParser
|
from jambo.parser._type_parser import GenericTypeParser
|
||||||
from jambo.types.type_parser_options import TypeParserOptions
|
from jambo.types.type_parser_options import TypeParserOptions
|
||||||
|
|
||||||
@@ -14,10 +15,15 @@ class AnyOfTypeParser(GenericTypeParser):
|
|||||||
self, name, properties, **kwargs: Unpack[TypeParserOptions]
|
self, name, properties, **kwargs: Unpack[TypeParserOptions]
|
||||||
):
|
):
|
||||||
if "anyOf" not in properties:
|
if "anyOf" not in properties:
|
||||||
raise ValueError(f"Invalid JSON Schema: {properties}")
|
raise InvalidSchemaException(
|
||||||
|
f"AnyOf type {name} must have 'anyOf' property defined.",
|
||||||
|
invalid_field="anyOf",
|
||||||
|
)
|
||||||
|
|
||||||
if not isinstance(properties["anyOf"], list):
|
if not isinstance(properties["anyOf"], list):
|
||||||
raise ValueError(f"Invalid JSON Schema: {properties['anyOf']}")
|
raise InvalidSchemaException(
|
||||||
|
"AnyOf must be a list of types.", invalid_field="anyOf"
|
||||||
|
)
|
||||||
|
|
||||||
mapped_properties = self.mappings_properties_builder(properties, **kwargs)
|
mapped_properties = self.mappings_properties_builder(properties, **kwargs)
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
from jambo.exceptions import InvalidSchemaException
|
||||||
from jambo.parser._type_parser import GenericTypeParser
|
from jambo.parser._type_parser import GenericTypeParser
|
||||||
from jambo.types.type_parser_options import TypeParserOptions
|
from jambo.types.type_parser_options import TypeParserOptions
|
||||||
|
|
||||||
@@ -26,8 +27,15 @@ class ArrayTypeParser(GenericTypeParser):
|
|||||||
):
|
):
|
||||||
item_properties = kwargs.copy()
|
item_properties = kwargs.copy()
|
||||||
item_properties["required"] = True
|
item_properties["required"] = True
|
||||||
|
|
||||||
|
if (items := properties.get("items")) is None:
|
||||||
|
raise InvalidSchemaException(
|
||||||
|
f"Array type {name} must have 'items' property defined.",
|
||||||
|
invalid_field="items",
|
||||||
|
)
|
||||||
|
|
||||||
_item_type, _item_args = GenericTypeParser.type_from_properties(
|
_item_type, _item_args = GenericTypeParser.type_from_properties(
|
||||||
name, properties["items"], **item_properties
|
name, items, **item_properties
|
||||||
)
|
)
|
||||||
|
|
||||||
wrapper_type = set if properties.get("uniqueItems", False) else list
|
wrapper_type = set if properties.get("uniqueItems", False) else list
|
||||||
@@ -47,8 +55,9 @@ class ArrayTypeParser(GenericTypeParser):
|
|||||||
return lambda: None
|
return lambda: None
|
||||||
|
|
||||||
if not isinstance(default_list, Iterable):
|
if not isinstance(default_list, Iterable):
|
||||||
raise ValueError(
|
raise InvalidSchemaException(
|
||||||
f"Default value for array must be an iterable, got {type(default_list)}"
|
f"Default value for array must be an iterable, got {type(default_list)}",
|
||||||
|
invalid_field="default",
|
||||||
)
|
)
|
||||||
|
|
||||||
return lambda: copy.deepcopy(wrapper_type(default_list))
|
return lambda: copy.deepcopy(wrapper_type(default_list))
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
from jambo.exceptions import InvalidSchemaException
|
||||||
from jambo.parser._type_parser import GenericTypeParser
|
from jambo.parser._type_parser import GenericTypeParser
|
||||||
from jambo.types.type_parser_options import TypeParserOptions
|
from jambo.types.type_parser_options import TypeParserOptions
|
||||||
|
|
||||||
@@ -20,6 +21,9 @@ class BooleanTypeParser(GenericTypeParser):
|
|||||||
|
|
||||||
default_value = properties.get("default")
|
default_value = properties.get("default")
|
||||||
if default_value is not None and not isinstance(default_value, bool):
|
if default_value is not None and not isinstance(default_value, bool):
|
||||||
raise ValueError(f"Default value for {name} must be a boolean.")
|
raise InvalidSchemaException(
|
||||||
|
f"Default value for {name} must be a boolean.",
|
||||||
|
invalid_field="default",
|
||||||
|
)
|
||||||
|
|
||||||
return bool, mapped_properties
|
return bool, mapped_properties
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
from jambo.exceptions import InvalidSchemaException
|
||||||
from jambo.parser._type_parser import GenericTypeParser
|
from jambo.parser._type_parser import GenericTypeParser
|
||||||
from jambo.types.json_schema_type import JSONSchemaNativeTypes
|
from jambo.types.json_schema_type import JSONSchemaNativeTypes
|
||||||
from jambo.types.type_parser_options import TypeParserOptions
|
from jambo.types.type_parser_options import TypeParserOptions
|
||||||
@@ -18,13 +19,17 @@ class ConstTypeParser(GenericTypeParser):
|
|||||||
self, name, properties, **kwargs: Unpack[TypeParserOptions]
|
self, name, properties, **kwargs: Unpack[TypeParserOptions]
|
||||||
):
|
):
|
||||||
if "const" not in properties:
|
if "const" not in properties:
|
||||||
raise ValueError(f"Const type {name} must have 'const' property defined.")
|
raise InvalidSchemaException(
|
||||||
|
f"Const type {name} must have 'const' property defined.",
|
||||||
|
invalid_field="const",
|
||||||
|
)
|
||||||
|
|
||||||
const_value = properties["const"]
|
const_value = properties["const"]
|
||||||
|
|
||||||
if not isinstance(const_value, JSONSchemaNativeTypes):
|
if not isinstance(const_value, JSONSchemaNativeTypes):
|
||||||
raise ValueError(
|
raise InvalidSchemaException(
|
||||||
f"Const type {name} must have 'const' value of allowed types: {JSONSchemaNativeTypes}."
|
f"Const type {name} must have 'const' value of allowed types: {JSONSchemaNativeTypes}.",
|
||||||
|
invalid_field="const",
|
||||||
)
|
)
|
||||||
|
|
||||||
const_type = self._build_const_type(const_value)
|
const_type = self._build_const_type(const_value)
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
from jambo.exceptions import InvalidSchemaException
|
||||||
from jambo.parser._type_parser import GenericTypeParser
|
from jambo.parser._type_parser import GenericTypeParser
|
||||||
from jambo.types.json_schema_type import JSONSchemaNativeTypes
|
from jambo.types.json_schema_type import JSONSchemaNativeTypes
|
||||||
from jambo.types.type_parser_options import JSONSchema, TypeParserOptions
|
from jambo.types.type_parser_options import JSONSchema, TypeParserOptions
|
||||||
@@ -14,16 +15,23 @@ class EnumTypeParser(GenericTypeParser):
|
|||||||
self, name: str, properties: JSONSchema, **kwargs: Unpack[TypeParserOptions]
|
self, name: str, properties: JSONSchema, **kwargs: Unpack[TypeParserOptions]
|
||||||
):
|
):
|
||||||
if "enum" not in properties:
|
if "enum" not in properties:
|
||||||
raise ValueError(f"Enum type {name} must have 'enum' property defined.")
|
raise InvalidSchemaException(
|
||||||
|
f"Enum type {name} must have 'enum' property defined.",
|
||||||
|
invalid_field="enum",
|
||||||
|
)
|
||||||
|
|
||||||
enum_values = properties["enum"]
|
enum_values = properties["enum"]
|
||||||
|
|
||||||
if not isinstance(enum_values, list):
|
if not isinstance(enum_values, list):
|
||||||
raise ValueError(f"Enum type {name} must have 'enum' as a list of values.")
|
raise InvalidSchemaException(
|
||||||
|
f"Enum type {name} must have 'enum' as a list of values.",
|
||||||
|
invalid_field="enum",
|
||||||
|
)
|
||||||
|
|
||||||
if any(not isinstance(value, JSONSchemaNativeTypes) for value in enum_values):
|
if any(not isinstance(value, JSONSchemaNativeTypes) for value in enum_values):
|
||||||
raise ValueError(
|
raise InvalidSchemaException(
|
||||||
f"Enum type {name} must have 'enum' values of allowed types: {JSONSchemaNativeTypes}."
|
f"Enum type {name} must have 'enum' values of allowed types: {JSONSchemaNativeTypes}.",
|
||||||
|
invalid_field="enum",
|
||||||
)
|
)
|
||||||
|
|
||||||
# Create a new Enum type dynamically
|
# Create a new Enum type dynamically
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
from jambo.exceptions import InvalidSchemaException
|
||||||
from jambo.parser._type_parser import GenericTypeParser
|
from jambo.parser._type_parser import GenericTypeParser
|
||||||
from jambo.types.type_parser_options import TypeParserOptions
|
from jambo.types.type_parser_options import TypeParserOptions
|
||||||
|
|
||||||
@@ -17,10 +18,14 @@ class OneOfTypeParser(GenericTypeParser):
|
|||||||
self, name, properties, **kwargs: Unpack[TypeParserOptions]
|
self, name, properties, **kwargs: Unpack[TypeParserOptions]
|
||||||
):
|
):
|
||||||
if "oneOf" not in properties:
|
if "oneOf" not in properties:
|
||||||
raise ValueError(f"Invalid JSON Schema: {properties}")
|
raise InvalidSchemaException(
|
||||||
|
f"Invalid JSON Schema: {properties}", invalid_field="oneOf"
|
||||||
|
)
|
||||||
|
|
||||||
if not isinstance(properties["oneOf"], list) or len(properties["oneOf"]) == 0:
|
if not isinstance(properties["oneOf"], list) or len(properties["oneOf"]) == 0:
|
||||||
raise ValueError(f"Invalid JSON Schema: {properties['oneOf']}")
|
raise InvalidSchemaException(
|
||||||
|
f"Invalid JSON Schema: {properties['oneOf']}", invalid_field="oneOf"
|
||||||
|
)
|
||||||
|
|
||||||
mapped_properties = self.mappings_properties_builder(properties, **kwargs)
|
mapped_properties = self.mappings_properties_builder(properties, **kwargs)
|
||||||
|
|
||||||
@@ -58,7 +63,9 @@ class OneOfTypeParser(GenericTypeParser):
|
|||||||
Build a type with a discriminator.
|
Build a type with a discriminator.
|
||||||
"""
|
"""
|
||||||
if not isinstance(discriminator_prop, dict):
|
if not isinstance(discriminator_prop, dict):
|
||||||
raise ValueError("Discriminator must be a dictionary")
|
raise InvalidSchemaException(
|
||||||
|
"Discriminator must be a dictionary", invalid_field="discriminator"
|
||||||
|
)
|
||||||
|
|
||||||
for field in subfield_types:
|
for field in subfield_types:
|
||||||
field_type, field_info = get_args(field)
|
field_type, field_info = get_args(field)
|
||||||
@@ -66,13 +73,17 @@ class OneOfTypeParser(GenericTypeParser):
|
|||||||
if issubclass(field_type, BaseModel):
|
if issubclass(field_type, BaseModel):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
raise ValueError(
|
raise InvalidSchemaException(
|
||||||
"When using a discriminator, all subfield types must be of type 'object'."
|
"When using a discriminator, all subfield types must be of type 'object'.",
|
||||||
|
invalid_field="discriminator",
|
||||||
)
|
)
|
||||||
|
|
||||||
property_name = discriminator_prop.get("propertyName")
|
property_name = discriminator_prop.get("propertyName")
|
||||||
if property_name is None or not isinstance(property_name, str):
|
if property_name is None or not isinstance(property_name, str):
|
||||||
raise ValueError("Discriminator must have a 'propertyName' key")
|
raise InvalidSchemaException(
|
||||||
|
"Discriminator must have a 'propertyName' key",
|
||||||
|
invalid_field="propertyName",
|
||||||
|
)
|
||||||
|
|
||||||
return Annotated[Union[(*subfield_types,)], Field(discriminator=property_name)]
|
return Annotated[Union[(*subfield_types,)], Field(discriminator=property_name)]
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
from jambo.exceptions import InvalidSchemaException
|
||||||
from jambo.parser import GenericTypeParser
|
from jambo.parser import GenericTypeParser
|
||||||
from jambo.types.json_schema_type import JSONSchema
|
from jambo.types.json_schema_type import JSONSchema
|
||||||
from jambo.types.type_parser_options import TypeParserOptions
|
from jambo.types.type_parser_options import TypeParserOptions
|
||||||
@@ -17,18 +18,21 @@ class RefTypeParser(GenericTypeParser):
|
|||||||
self, name: str, properties: JSONSchema, **kwargs: Unpack[TypeParserOptions]
|
self, name: str, properties: JSONSchema, **kwargs: Unpack[TypeParserOptions]
|
||||||
) -> tuple[RefType, dict]:
|
) -> tuple[RefType, dict]:
|
||||||
if "$ref" not in properties:
|
if "$ref" not in properties:
|
||||||
raise ValueError(f"RefTypeParser: Missing $ref in properties for {name}")
|
raise InvalidSchemaException(
|
||||||
|
f"Missing $ref in properties for {name}", invalid_field="$ref"
|
||||||
|
)
|
||||||
|
|
||||||
context = kwargs.get("context")
|
context = kwargs.get("context")
|
||||||
if context is None:
|
if context is None:
|
||||||
raise RuntimeError(
|
raise InvalidSchemaException(
|
||||||
f"RefTypeParser: Missing `content` in properties for {name}"
|
f"Missing `context` in properties for {name}", invalid_field="context"
|
||||||
)
|
)
|
||||||
|
|
||||||
ref_cache = kwargs.get("ref_cache")
|
ref_cache = kwargs.get("ref_cache")
|
||||||
if ref_cache is None:
|
if ref_cache is None:
|
||||||
raise RuntimeError(
|
raise InvalidSchemaException(
|
||||||
f"RefTypeParser: Missing `ref_cache` in properties for {name}"
|
f"Missing `ref_cache` in properties for {name}",
|
||||||
|
invalid_field="ref_cache",
|
||||||
)
|
)
|
||||||
|
|
||||||
mapped_properties = self.mappings_properties_builder(properties, **kwargs)
|
mapped_properties = self.mappings_properties_builder(properties, **kwargs)
|
||||||
@@ -63,8 +67,8 @@ class RefTypeParser(GenericTypeParser):
|
|||||||
ref_name, ref_property, **kwargs
|
ref_name, ref_property, **kwargs
|
||||||
)
|
)
|
||||||
case _:
|
case _:
|
||||||
raise ValueError(
|
raise InvalidSchemaException(
|
||||||
f"RefTypeParser: Unsupported $ref {ref_property['$ref']}"
|
f"Unsupported $ref {ref_property['$ref']}", invalid_field="$ref"
|
||||||
)
|
)
|
||||||
|
|
||||||
return mapped_type
|
return mapped_type
|
||||||
@@ -93,8 +97,9 @@ class RefTypeParser(GenericTypeParser):
|
|||||||
if properties.get("$ref") == "#":
|
if properties.get("$ref") == "#":
|
||||||
ref_name = kwargs["context"].get("title")
|
ref_name = kwargs["context"].get("title")
|
||||||
if ref_name is None:
|
if ref_name is None:
|
||||||
raise ValueError(
|
raise InvalidSchemaException(
|
||||||
"RefTypeParser: Missing title in properties for $ref of Root Reference"
|
"Missing title in properties for $ref of Root Reference",
|
||||||
|
invalid_field="title",
|
||||||
)
|
)
|
||||||
return "forward_ref", ref_name, {}
|
return "forward_ref", ref_name, {}
|
||||||
|
|
||||||
@@ -104,8 +109,9 @@ class RefTypeParser(GenericTypeParser):
|
|||||||
)
|
)
|
||||||
return "def_ref", target_name, target_property
|
return "def_ref", target_name, target_property
|
||||||
|
|
||||||
raise ValueError(
|
raise InvalidSchemaException(
|
||||||
"RefTypeParser: Only Root and $defs references are supported at the moment"
|
"Only Root and $defs references are supported at the moment",
|
||||||
|
invalid_field="$ref",
|
||||||
)
|
)
|
||||||
|
|
||||||
def _extract_target_ref(
|
def _extract_target_ref(
|
||||||
@@ -115,14 +121,16 @@ class RefTypeParser(GenericTypeParser):
|
|||||||
target_property = kwargs["context"]
|
target_property = kwargs["context"]
|
||||||
for prop_name in properties["$ref"].split("/")[1:]:
|
for prop_name in properties["$ref"].split("/")[1:]:
|
||||||
if prop_name not in target_property:
|
if prop_name not in target_property:
|
||||||
raise ValueError(
|
raise InvalidSchemaException(
|
||||||
f"RefTypeParser: Missing {prop_name} in"
|
f"Missing {prop_name} in properties for $ref {properties['$ref']}",
|
||||||
" properties for $ref {properties['$ref']}"
|
invalid_field=prop_name,
|
||||||
)
|
)
|
||||||
target_name = prop_name
|
target_name = prop_name
|
||||||
target_property = target_property[prop_name] # type: ignore
|
target_property = target_property[prop_name] # type: ignore
|
||||||
|
|
||||||
if not isinstance(target_name, str) or target_property is None:
|
if not isinstance(target_name, str) or target_property is None:
|
||||||
raise ValueError(f"RefTypeParser: Invalid $ref {properties['$ref']}")
|
raise InvalidSchemaException(
|
||||||
|
f"Invalid $ref {properties['$ref']}", invalid_field="$ref"
|
||||||
|
)
|
||||||
|
|
||||||
return target_name, target_property
|
return target_name, target_property
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
from jambo.exceptions import InvalidSchemaException
|
||||||
from jambo.parser._type_parser import GenericTypeParser
|
from jambo.parser._type_parser import GenericTypeParser
|
||||||
from jambo.types.type_parser_options import TypeParserOptions
|
from jambo.types.type_parser_options import TypeParserOptions
|
||||||
|
|
||||||
@@ -54,7 +55,9 @@ class StringTypeParser(GenericTypeParser):
|
|||||||
return str, mapped_properties
|
return str, mapped_properties
|
||||||
|
|
||||||
if format_type not in self.format_type_mapping:
|
if format_type not in self.format_type_mapping:
|
||||||
raise ValueError(f"Unsupported string format: {format_type}")
|
raise InvalidSchemaException(
|
||||||
|
f"Unsupported string format: {format_type}", invalid_field="format"
|
||||||
|
)
|
||||||
|
|
||||||
mapped_type = self.format_type_mapping[format_type]
|
mapped_type = self.format_type_mapping[format_type]
|
||||||
if format_type in self.format_pattern_mapping:
|
if format_type in self.format_pattern_mapping:
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ JSONSchema = TypedDict(
|
|||||||
"minProperties": int,
|
"minProperties": int,
|
||||||
"maxProperties": int,
|
"maxProperties": int,
|
||||||
"dependencies": Dict[str, Union[List[str], "JSONSchema"]],
|
"dependencies": Dict[str, Union[List[str], "JSONSchema"]],
|
||||||
"items": Union["JSONSchema", List["JSONSchema"]],
|
"items": "JSONSchema",
|
||||||
"prefixItems": List["JSONSchema"],
|
"prefixItems": List["JSONSchema"],
|
||||||
"additionalItems": Union[bool, "JSONSchema"],
|
"additionalItems": Union[bool, "JSONSchema"],
|
||||||
"contains": "JSONSchema",
|
"contains": "JSONSchema",
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ class TestRefTypeParser(TestCase):
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
with self.assertRaises(RuntimeError):
|
with self.assertRaises(ValueError):
|
||||||
RefTypeParser().from_properties(
|
RefTypeParser().from_properties(
|
||||||
"person",
|
"person",
|
||||||
properties,
|
properties,
|
||||||
@@ -63,7 +63,7 @@ class TestRefTypeParser(TestCase):
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
with self.assertRaises(RuntimeError):
|
with self.assertRaises(ValueError):
|
||||||
RefTypeParser().from_properties(
|
RefTypeParser().from_properties(
|
||||||
"person",
|
"person",
|
||||||
properties,
|
properties,
|
||||||
|
|||||||
@@ -187,7 +187,8 @@ class TestStringTypeParser(TestCase):
|
|||||||
parser.from_properties("placeholder", properties)
|
parser.from_properties("placeholder", properties)
|
||||||
|
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
str(context.exception), "Unsupported string format: unsupported-format"
|
str(context.exception),
|
||||||
|
"Invalid JSON Schema: Unsupported string format: unsupported-format (invalid field: format)",
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_string_parser_with_date_format(self):
|
def test_string_parser_with_date_format(self):
|
||||||
|
|||||||
Reference in New Issue
Block a user