CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-cerberus

Lightweight, extensible schema and data validation tool for Python dictionaries.

Overview
Eval results
Files

error-handling.mddocs/

Error Handling

Cerberus provides a comprehensive error handling system with detailed error representation, organization, and customizable formatting. The system captures precise validation failures with context and supports custom error handlers for different output formats.

Capabilities

ValidationError Class

Detailed representation of individual validation failures.

class ValidationError:
    def __init__(self, document_path, schema_path, code, rule, constraint, value, info):
        """
        Create a validation error.
        
        Parameters:
        - document_path: Path to field within document (tuple)
        - schema_path: Path to rule within schema (tuple)
        - code: Error identifier code (int)
        - rule: Rule that failed validation (str)
        - constraint: Constraint that failed
        - value: Value that caused failure
        - info: Additional error details (tuple)
        """

    @property
    def document_path(self) -> tuple:
        """Path to the field within the document that caused the error"""

    @property
    def schema_path(self) -> tuple:
        """Path to the rule within the schema that caused the error"""

    @property
    def code(self) -> int:
        """Error identifier code"""

    @property
    def rule(self) -> str:
        """Rule that failed validation"""

    @property
    def constraint(self):
        """Constraint that failed"""

    @property
    def value(self):
        """Value that caused the failure"""

    @property
    def info(self) -> tuple:
        """Additional error information"""

    @property
    def field(self):
        """Field name from document path"""

    @property
    def child_errors(self):
        """List of individual errors for bulk validation errors"""

    @property
    def definitions_errors(self):
        """Errors mapped to definition indices for *of-rules"""

    @property
    def is_group_error(self) -> bool:
        """True for bulk validation errors"""

    @property
    def is_logic_error(self) -> bool:
        """True for *of-rule validation errors"""

    @property
    def is_normalization_error(self) -> bool:
        """True for normalization errors"""

Error Collections

Specialized collections for organizing validation errors.

class ErrorList(list):
    """
    List of ValidationError instances with queryable interface.
    Supports 'in' keyword for ErrorDefinition instances.
    """

Error Trees

Hierarchical organization of validation errors.

class ErrorTree:
    """Base class for organizing errors in tree structures"""
    
    def add(self, error):
        """
        Add ValidationError to tree.
        
        Parameters:
        - error: ValidationError to add
        """

    def fetch_errors_from(self, path):
        """
        Get all errors for a given path.
        
        Parameters:
        - path: Path to fetch errors for (tuple)
        
        Returns:
        list: Errors at the specified path
        """

    def fetch_node_from(self, path):
        """
        Get tree node for a given path.
        
        Parameters:
        - path: Path to fetch node for (tuple)
        
        Returns:
        Tree node at the specified path
        """

class DocumentErrorTree(ErrorTree):
    """Error tree following document field structure"""

class SchemaErrorTree(ErrorTree):
    """Error tree following schema rule structure"""

Error Handlers

Customizable error formatting and output.

class BaseErrorHandler:
    """Abstract base class for all error handlers"""
    
    def __call__(self, errors):
        """
        Format errors for output.
        
        Parameters:
        - errors: Errors to format
        
        Returns:
        Formatted error output
        """

    def add(self, error):
        """
        Add error to handler.
        
        Parameters:
        - error: ValidationError to add
        """

    def extend(self, errors):
        """
        Add multiple errors.
        
        Parameters:
        - errors: Iterable of ValidationError instances
        """

    def emit(self, error):
        """
        Optionally emit error to stream.
        
        Parameters:
        - error: ValidationError to emit
        """

    def start(self, validator):
        """
        Called when validation starts.
        
        Parameters:
        - validator: Validator instance starting validation
        """

    def end(self, validator):
        """
        Called when validation ends.
        
        Parameters:
        - validator: Validator instance ending validation
        """

class BasicErrorHandler(BaseErrorHandler):
    """Default error handler that returns errors as nested dict"""
    
    @property
    def messages(self) -> dict:
        """Error code to message template mapping"""

    @property
    def tree(self):
        """Raw error tree structure"""

    @property
    def pretty_tree(self):
        """Cleaned error tree for display"""

class ToyErrorHandler(BaseErrorHandler):
    """Minimal error handler for child validators"""

class SchemaErrorHandler(BaseErrorHandler):
    """Specialized error handler for schema validation errors"""

Error Definition Constants

Pre-defined error codes and types for different validation failures.

# Existence Errors
CUSTOM: ErrorDefinition                # Custom validation errors (0x00)
DOCUMENT_MISSING: str                  # Document is missing
REQUIRED_FIELD: ErrorDefinition        # Required field missing (0x02)
UNKNOWN_FIELD: ErrorDefinition         # Unknown field present (0x03)
DEPENDENCIES_FIELD: ErrorDefinition    # Field dependency failed (0x04)
DEPENDENCIES_FIELD_VALUE: ErrorDefinition  # Field dependency value failed (0x05)
EXCLUDES_FIELD: ErrorDefinition        # Field exclusion failed (0x06)

# Shape Errors
DOCUMENT_FORMAT: str                   # Document format invalid
EMPTY_NOT_ALLOWED: ErrorDefinition     # Empty value not allowed (0x22)
NOT_NULLABLE: ErrorDefinition          # Null value not allowed (0x23)
BAD_TYPE: ErrorDefinition              # Type constraint failed (0x24)
BAD_TYPE_FOR_SCHEMA: ErrorDefinition   # Schema type constraint failed (0x25)
ITEMS_LENGTH: ErrorDefinition          # Items length constraint failed (0x26)
MIN_LENGTH: ErrorDefinition            # Minimum length constraint failed (0x27)
MAX_LENGTH: ErrorDefinition            # Maximum length constraint failed (0x28)

# Value Errors
REGEX_MISMATCH: ErrorDefinition        # Regex pattern match failed (0x41)
MIN_VALUE: ErrorDefinition             # Minimum value constraint failed (0x42)
MAX_VALUE: ErrorDefinition             # Maximum value constraint failed (0x43)
UNALLOWED_VALUE: ErrorDefinition       # Value not in allowed list (0x44)
UNALLOWED_VALUES: ErrorDefinition      # Values not in allowed list (0x45)
FORBIDDEN_VALUE: ErrorDefinition       # Value in forbidden list (0x46)
FORBIDDEN_VALUES: ErrorDefinition      # Values in forbidden list (0x47)
MISSING_MEMBERS: ErrorDefinition       # Required members missing (0x48)

# Processing Errors
NORMALIZATION: ErrorDefinition         # Normalization failed (0x60)
COERCION_FAILED: ErrorDefinition       # Type coercion failed (0x61)
RENAMING_FAILED: ErrorDefinition       # Field renaming failed (0x62)
READONLY_FIELD: ErrorDefinition        # Readonly field modified (0x63)
SETTING_DEFAULT_FAILED: ErrorDefinition  # Default value setting failed (0x64)

# Group Errors
ERROR_GROUP: ErrorDefinition           # Error group container (0x80)
MAPPING_SCHEMA: ErrorDefinition        # Mapping schema failed (0x81)
SEQUENCE_SCHEMA: ErrorDefinition       # Sequence schema failed (0x82)
KEYSRULES: ErrorDefinition             # Keys rules failed (0x83)
VALUESRULES: ErrorDefinition           # Values rules failed (0x84)
BAD_ITEMS: ErrorDefinition             # Items constraint failed (0x8F)

# Logical Errors
LOGICAL: ErrorDefinition               # Logical constraint failed (0x90)
NONEOF: ErrorDefinition                # None-of constraint failed (0x91)
ONEOF: ErrorDefinition                 # One-of constraint failed (0x92)
ANYOF: ErrorDefinition                 # Any-of constraint failed (0x93)
ALLOF: ErrorDefinition                 # All-of constraint failed (0x94)

Helper Types

ErrorDefinition = namedtuple('ErrorDefinition', 'code rule')
    """Defines error types with unique code and associated rule"""

Usage Examples

Basic Error Handling

from cerberus import Validator

schema = {
    'name': {'type': 'string', 'minlength': 2},
    'age': {'type': 'integer', 'min': 0, 'max': 150},
    'email': {'type': 'string', 'required': True}
}

v = Validator(schema)

# Invalid document
document = {
    'name': 'A',       # Too short
    'age': -5,         # Below minimum
    # 'email' missing  # Required field missing
}

if not v.validate(document):
    print("Validation failed!")
    print("Errors:", v.errors)
    # Output: {
    #     'name': ['min length is 2'],
    #     'age': ['min value is 0'],
    #     'email': ['required field']
    # }

Detailed Error Information

from cerberus import Validator

v = Validator({'name': {'type': 'string'}})
v.validate({'name': 123})

# Access error tree for detailed information
error_tree = v.document_error_tree
print(error_tree.errors)

# Access individual validation errors
for error in error_tree.errors:
    print(f"Field: {error.field}")
    print(f"Rule: {error.rule}")
    print(f"Code: {error.code}")
    print(f"Value: {error.value}")
    print(f"Path: {error.document_path}")

Custom Error Handler

from cerberus import Validator
from cerberus.errors import BaseErrorHandler

class CustomErrorHandler(BaseErrorHandler):
    def __call__(self, errors):
        """Return simple list of error messages"""
        messages = []
        for field_errors in errors.values():
            messages.extend(field_errors)
        return messages

# Use custom handler
v = Validator({'name': {'type': 'string'}}, error_handler=CustomErrorHandler)
v.validate({'name': 123})
print(v.errors)  # ['must be of string type']

Error Handler with Initialization

from cerberus import Validator
from cerberus.errors import BasicErrorHandler

# Pass handler as tuple with initialization arguments
error_handler_config = (BasicErrorHandler, {'some_option': 'value'})
v = Validator(schema, error_handler=error_handler_config)

Error Tree Navigation

from cerberus import Validator

schema = {
    'user': {
        'type': 'dict',
        'schema': {
            'name': {'type': 'string'},
            'contacts': {
                'type': 'list',
                'schema': {
                    'type': 'dict',
                    'schema': {
                        'type': {'type': 'string', 'allowed': ['email', 'phone']},
                        'value': {'type': 'string'}
                    }
                }
            }
        }
    }
}

document = {
    'user': {
        'name': 123,  # Invalid type
        'contacts': [
            {'type': 'invalid', 'value': 'test@example.com'},  # Invalid type
            {'type': 'email'}  # Missing value
        ]
    }
}

v = Validator(schema)
v.validate(document)

# Navigate error tree
error_tree = v.document_error_tree

# Get errors for specific paths
name_errors = error_tree.fetch_errors_from(('user', 'name'))
contact_errors = error_tree.fetch_errors_from(('user', 'contacts', 0, 'type'))

print("Name errors:", name_errors)
print("Contact type errors:", contact_errors)

Error Code Checking

from cerberus import Validator
from cerberus.errors import BAD_TYPE, REQUIRED_FIELD

v = Validator({'name': {'type': 'string', 'required': True}})
v.validate({'name': 123})

# Check if specific error types occurred
error_tree = v.document_error_tree
errors = error_tree.errors

for error in errors:
    if error.code == BAD_TYPE.code:
        print(f"Type error in field {error.field}: expected string, got {type(error.value).__name__}")
    elif error.code == REQUIRED_FIELD.code:
        print(f"Missing required field: {error.field}")

Error Emission and Streaming

from cerberus import Validator
from cerberus.errors import BaseErrorHandler
import sys

class StreamingErrorHandler(BaseErrorHandler):
    def emit(self, error):
        """Emit errors to stderr as they occur"""
        print(f"Validation error: {error.field} - {error.rule}", file=sys.stderr)
    
    def __call__(self, errors):
        """Return standard error format"""
        return errors

v = Validator({'name': {'type': 'string'}}, error_handler=StreamingErrorHandler)
# Errors will be printed to stderr during validation
v.validate({'name': 123})

Pretty Error Trees

from cerberus import Validator
from cerberus.errors import BasicErrorHandler

v = Validator({'user': {'type': 'dict', 'schema': {'name': {'type': 'string'}}}})
v.validate({'user': {'name': 123}})

# Access pretty-formatted error tree
if hasattr(v.error_handler, 'pretty_tree'):
    pretty_errors = v.error_handler.pretty_tree
    print("Pretty errors:", pretty_errors)

Install with Tessl CLI

npx tessl i tessl/pypi-cerberus

docs

advanced-features.md

core-validation.md

error-handling.md

index.md

schema-management.md

type-system.md

tile.json