feat: alters all standart errors and messages for more specific errors

This commit is contained in:
2025-09-14 00:05:21 -03:00
parent f4d84d2749
commit 30290771b1
11 changed files with 94 additions and 39 deletions

View File

@@ -1,3 +1,4 @@
from jambo.exceptions import InvalidSchemaException
from jambo.parser._type_parser import GenericTypeParser
from jambo.types.type_parser_options import TypeParserOptions
@@ -14,10 +15,15 @@ class AnyOfTypeParser(GenericTypeParser):
self, name, properties, **kwargs: Unpack[TypeParserOptions]
):
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):
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)

View File

@@ -1,3 +1,4 @@
from jambo.exceptions import InvalidSchemaException
from jambo.parser._type_parser import GenericTypeParser
from jambo.types.type_parser_options import TypeParserOptions
@@ -26,8 +27,15 @@ class ArrayTypeParser(GenericTypeParser):
):
item_properties = kwargs.copy()
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(
name, properties["items"], **item_properties
name, items, **item_properties
)
wrapper_type = set if properties.get("uniqueItems", False) else list
@@ -47,8 +55,9 @@ class ArrayTypeParser(GenericTypeParser):
return lambda: None
if not isinstance(default_list, Iterable):
raise ValueError(
f"Default value for array must be an iterable, got {type(default_list)}"
raise InvalidSchemaException(
f"Default value for array must be an iterable, got {type(default_list)}",
invalid_field="default",
)
return lambda: copy.deepcopy(wrapper_type(default_list))

View File

@@ -1,3 +1,4 @@
from jambo.exceptions import InvalidSchemaException
from jambo.parser._type_parser import GenericTypeParser
from jambo.types.type_parser_options import TypeParserOptions
@@ -20,6 +21,9 @@ class BooleanTypeParser(GenericTypeParser):
default_value = properties.get("default")
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

View File

@@ -1,3 +1,4 @@
from jambo.exceptions import InvalidSchemaException
from jambo.parser._type_parser import GenericTypeParser
from jambo.types.json_schema_type import JSONSchemaNativeTypes
from jambo.types.type_parser_options import TypeParserOptions
@@ -18,13 +19,17 @@ class ConstTypeParser(GenericTypeParser):
self, name, properties, **kwargs: Unpack[TypeParserOptions]
):
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"]
if not isinstance(const_value, JSONSchemaNativeTypes):
raise ValueError(
f"Const type {name} must have 'const' value of allowed types: {JSONSchemaNativeTypes}."
raise InvalidSchemaException(
f"Const type {name} must have 'const' value of allowed types: {JSONSchemaNativeTypes}.",
invalid_field="const",
)
const_type = self._build_const_type(const_value)

View File

@@ -1,3 +1,4 @@
from jambo.exceptions import InvalidSchemaException
from jambo.parser._type_parser import GenericTypeParser
from jambo.types.json_schema_type import JSONSchemaNativeTypes
from jambo.types.type_parser_options import JSONSchema, TypeParserOptions
@@ -14,16 +15,23 @@ class EnumTypeParser(GenericTypeParser):
self, name: str, properties: JSONSchema, **kwargs: Unpack[TypeParserOptions]
):
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"]
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):
raise ValueError(
f"Enum type {name} must have 'enum' values of allowed types: {JSONSchemaNativeTypes}."
raise InvalidSchemaException(
f"Enum type {name} must have 'enum' values of allowed types: {JSONSchemaNativeTypes}.",
invalid_field="enum",
)
# Create a new Enum type dynamically

View File

@@ -1,3 +1,4 @@
from jambo.exceptions import InvalidSchemaException
from jambo.parser._type_parser import GenericTypeParser
from jambo.types.type_parser_options import TypeParserOptions
@@ -17,10 +18,14 @@ class OneOfTypeParser(GenericTypeParser):
self, name, properties, **kwargs: Unpack[TypeParserOptions]
):
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:
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)
@@ -58,7 +63,9 @@ class OneOfTypeParser(GenericTypeParser):
Build a type with a discriminator.
"""
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:
field_type, field_info = get_args(field)
@@ -66,13 +73,17 @@ class OneOfTypeParser(GenericTypeParser):
if issubclass(field_type, BaseModel):
continue
raise ValueError(
"When using a discriminator, all subfield types must be of type 'object'."
raise InvalidSchemaException(
"When using a discriminator, all subfield types must be of type 'object'.",
invalid_field="discriminator",
)
property_name = discriminator_prop.get("propertyName")
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)]

View File

@@ -1,3 +1,4 @@
from jambo.exceptions import InvalidSchemaException
from jambo.parser import GenericTypeParser
from jambo.types.json_schema_type import JSONSchema
from jambo.types.type_parser_options import TypeParserOptions
@@ -17,18 +18,21 @@ class RefTypeParser(GenericTypeParser):
self, name: str, properties: JSONSchema, **kwargs: Unpack[TypeParserOptions]
) -> tuple[RefType, dict]:
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")
if context is None:
raise RuntimeError(
f"RefTypeParser: Missing `content` in properties for {name}"
raise InvalidSchemaException(
f"Missing `context` in properties for {name}", invalid_field="context"
)
ref_cache = kwargs.get("ref_cache")
if ref_cache is None:
raise RuntimeError(
f"RefTypeParser: Missing `ref_cache` in properties for {name}"
raise InvalidSchemaException(
f"Missing `ref_cache` in properties for {name}",
invalid_field="ref_cache",
)
mapped_properties = self.mappings_properties_builder(properties, **kwargs)
@@ -63,8 +67,8 @@ class RefTypeParser(GenericTypeParser):
ref_name, ref_property, **kwargs
)
case _:
raise ValueError(
f"RefTypeParser: Unsupported $ref {ref_property['$ref']}"
raise InvalidSchemaException(
f"Unsupported $ref {ref_property['$ref']}", invalid_field="$ref"
)
return mapped_type
@@ -93,8 +97,9 @@ class RefTypeParser(GenericTypeParser):
if properties.get("$ref") == "#":
ref_name = kwargs["context"].get("title")
if ref_name is None:
raise ValueError(
"RefTypeParser: Missing title in properties for $ref of Root Reference"
raise InvalidSchemaException(
"Missing title in properties for $ref of Root Reference",
invalid_field="title",
)
return "forward_ref", ref_name, {}
@@ -104,8 +109,9 @@ class RefTypeParser(GenericTypeParser):
)
return "def_ref", target_name, target_property
raise ValueError(
"RefTypeParser: Only Root and $defs references are supported at the moment"
raise InvalidSchemaException(
"Only Root and $defs references are supported at the moment",
invalid_field="$ref",
)
def _extract_target_ref(
@@ -115,14 +121,16 @@ class RefTypeParser(GenericTypeParser):
target_property = kwargs["context"]
for prop_name in properties["$ref"].split("/")[1:]:
if prop_name not in target_property:
raise ValueError(
f"RefTypeParser: Missing {prop_name} in"
" properties for $ref {properties['$ref']}"
raise InvalidSchemaException(
f"Missing {prop_name} in properties for $ref {properties['$ref']}",
invalid_field=prop_name,
)
target_name = prop_name
target_property = target_property[prop_name] # type: ignore
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

View File

@@ -1,3 +1,4 @@
from jambo.exceptions import InvalidSchemaException
from jambo.parser._type_parser import GenericTypeParser
from jambo.types.type_parser_options import TypeParserOptions
@@ -54,7 +55,9 @@ class StringTypeParser(GenericTypeParser):
return str, mapped_properties
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]
if format_type in self.format_pattern_mapping:

View File

@@ -52,7 +52,7 @@ JSONSchema = TypedDict(
"minProperties": int,
"maxProperties": int,
"dependencies": Dict[str, Union[List[str], "JSONSchema"]],
"items": Union["JSONSchema", List["JSONSchema"]],
"items": "JSONSchema",
"prefixItems": List["JSONSchema"],
"additionalItems": Union[bool, "JSONSchema"],
"contains": "JSONSchema",