Faults — Aquilia Documentation
Comprehensive guide and documentation for Faults in the Aquilia framework. View API reference, examples, and implementation patterns.
Contracts / Faults Contract Faults Contracts use structured fault types instead of bare exceptions. All Contract errors are part of the CONTRACT fault domain and integrate seamlessly with the AquilaFaults error handling system. Fault Taxonomy , , , , , , ].map((item, i) => ( ))} CastFault Raised when a Facet cannot coerce a raw value to the expected Python type: from aquilia.contracts.exceptions import CastFault # CastFault is raised internally during Phase 1 (Cast) # Typically caught by the Contract and added to errors dict # Example triggers: # IntFacet receives "not a number" # DateTimeFacet receives "invalid date" # BoolFacet receives [1, 2, 3] # EmailFacet receives "not@an@email" try: facet = IntFacet() facet.cast("hello") except CastFault as e: print(e.field) # "quantity" print(e.message) # "Expected integer, got str" print(e.code) # "BP100" SealFault Raised when validation fails — either from Facet constraints or from custom seal methods: from aquilia.contracts.exceptions import SealFault bp = ProductContract(data= ) # SealFault accumulates all errors bp.is_sealed() print(bp.errors) # # With raise_fault=True: try: bp.is_sealed(raise_fault=True) except SealFault as e: print(e.field_errors) # dict of field → error messages print(e.error_count) # Total number of errors print(e.as_response_body()) # # } Handling Contract Faults from aquilia import Controller, Post from aquilia.faults import fault_handler from aquilia.contracts.exceptions import SealFault class ProductController(Controller): prefix = "/api/products" @Post("/", status_code=201) async def create(self, ctx, payload: ProductContract): # Pattern 1: Check and return errors if not payload.is_sealed(): return ctx.json(payload.errors, status=422) product = payload.imprint() await product.save() return ctx.json(ProductContract(instance=product).data, status=201) # Pattern 2: Global fault handler for SealFault @fault_handler(SealFault) async def handle_seal_fault(ctx, fault): """Auto-converts SealFault to 422 response.""" return ctx.json(fault.as_response_body(), status=422) # Register in workspace: # workspace = Workspace(fault_handlers=[handle_seal_fault]) # Pattern 3: raise_fault=True for exception-based flow class StrictProductController(Controller): prefix = "/api/strict/products" @Post("/") async def create(self, ctx, payload: ProductContract): # This raises SealFault if validation fails # The global fault handler catches it automatically payload.is_sealed(raise_fault=True) product = payload.imprint() await product.save() return ctx.json(ProductContract(instance=product).data, status=201) Integration with AquilaFaults All Contract faults inherit from Fault and integrate with Aquilia's fault engine: from aquilia.faults.core import Fault, Severity, FaultDomain from aquilia.contracts.exceptions import SealFault, CastFault # All Contract faults have: fault = SealFault(field="email", message="Invalid email") fault.code # "BP200" fault.severity # Severity.WARN fault.domain # FaultDomain.CONTRACT (or VALIDATION) fault.public # True (safe to show to user) fault.retryable # False (fix the input, don't retry) # They appear in the FaultEngine's error log # They are caught by global fault handlers # They integrate with the trace/observability system )
Go to Homepage