Exceptions¶
Error classes for handling HyperBinder API errors.
All exceptions include:
error_code: A unique identifier (e.g., "HB-E001")suggestion: Actionable fix recommendationdetails: Additional context (optional)
Base Exception¶
HyperBinderError¶
hybi.HyperBinderError
¶
Bases: Exception
Base exception for all HyperBinder errors.
Attributes:
| Name | Type | Description |
|---|---|---|
message |
Human-readable error description |
|
error_code |
str
|
Machine-readable error code (e.g., "HB-E001") |
details |
Additional structured error information |
|
suggestion |
Actionable fix suggestion (if available) |
Connection Errors¶
ConnectionError¶
hybi.ConnectionError
¶
Authentication Errors¶
AuthenticationError¶
hybi.AuthenticationError
¶
Collection Errors¶
CollectionNotFoundError¶
hybi.CollectionNotFoundError
¶
Data Errors¶
IngestionError¶
hybi.IngestionError
¶
ValidationError¶
hybi.ValidationError
¶
Query Errors¶
QueryError¶
hybi.QueryError
¶
Schema Errors¶
SchemaError¶
Raised when a query operation is not supported by the schema type.
hybi.compose.SchemaError
¶
SlotError¶
Raised when an invalid field name is used in a query.
from hybi.compose.errors import SlotError
# Raised when querying with invalid field name
try:
results = q.find(nonexistent_field="value")
except SlotError as e:
print(f"Invalid field: {e.slot}")
print(f"Valid fields: {e.valid_slots}")
hybi.compose.SlotError
¶
AmbiguousFieldError¶
Raised when a field name appears in multiple nested locations.
from hybi.compose.errors import AmbiguousFieldError
# If schema has same column name in multiple places
try:
results = q.find(name="Alice") # "name" exists in both subject and object
except AmbiguousFieldError as e:
print(f"Ambiguous field: {e.field_name}")
print(f"Found at: {e.locations}") # ["subject.right", "object.right"]
print(f"Use dot notation: q.find(**{{'subject.right': 'Alice'}})")
hybi.compose.errors.AmbiguousFieldError
¶
Bases: HyperBinderError
Field name is ambiguous (appears in multiple nested paths).
Raised when a column name appears in multiple nested structures and the query cannot determine which one to use.
Example
schema = Triple( ... subject=Pair(left=Field("type"), right=Field("name")), ... object=Pair(left=Field("type"), right=Field("name")), # "type" appears twice! ... ) q.find(type="Person") # Ambiguous - which "type"? AmbiguousFieldError: Ambiguous field 'type' - appears in ['subject.left', 'object.left']
Compose Validation Errors¶
FieldValidationError¶
Raised when field validation fails against data.
from hybi.compose.errors import FieldValidationError
try:
hb.ingest(df, collection="data", schema=schema)
except FieldValidationError as e:
print(f"Field: {e.field}")
print(f"Severity: {e.severity}") # "error" or "warning"
hybi.compose.FieldValidationError
¶
CompositionError¶
Raised when attempting invalid molecule nesting.
Terminal molecules (like Bundle) cannot be nested inside composable molecules because their encoding is not compatible with structured composition.
from hybi.compose.errors import CompositionError
# Would be raised for invalid nesting:
# Triple(subject=Bundle(...), ...) # Bundle cannot be nested
hybi.compose.CompositionError
¶
Bases: HyperBinderError
Invalid molecule composition.
Raised when attempting to nest terminal molecules (like Record) inside composable molecules (like Triple, Pair, etc.).
Terminal molecules use bundle encoding which cannot be composed with chain-based molecules while preserving extraction fidelity.
Table/CRUD Errors¶
These errors are raised by exact lookup operations (get(), update(), delete()).
NotFoundError¶
Raised when get() finds no matching row.
from hybi.compose.errors import NotFoundError
try:
user = hb.query("users", schema).get(user_id="U999")
except NotFoundError as e:
print(f"Conditions: {e.conditions}")
print(f"Collection: {e.collection}")
print(f"Suggestion: {e.suggestion}")
hybi.compose.NotFoundError
¶
Bases: HyperBinderError
No row matches exact lookup conditions.
Raised by get() when the specified key/value combination does not exist in the collection.
Example
user = table.query(schema).get(user_id="U999") NotFoundError: No row found matching {'user_id': 'U999'}
MultipleFoundError¶
Raised when get() finds multiple rows (violates uniqueness).
from hybi.compose.errors import MultipleFoundError
try:
user = hb.query("users", schema).get(email="duplicate@example.com")
except MultipleFoundError as e:
print(f"Found {e.count}+ rows matching {e.conditions}")
hybi.compose.MultipleFoundError
¶
Bases: HyperBinderError
Multiple rows match exact lookup (violates uniqueness).
Raised by get() when more than one row matches the conditions, indicating a schema or data integrity issue.
Example
user = table.query(schema).get(email="alice@example.com") MultipleFoundError: Multiple rows match {'email': 'alice@example.com'}
EncodingMismatchError¶
Raised when field encoding is incompatible with the operation.
from hybi.compose.errors import EncodingMismatchError
try:
# get() requires EXACT encoding for deterministic lookup
user = hb.query("users", schema).get(bio="machine learning")
except EncodingMismatchError as e:
print(f"Field '{e.field}' has {e.actual_encoding} encoding")
print(f"Required: {e.required_encoding}")
hybi.compose.EncodingMismatchError
¶
Bases: HyperBinderError
Field encoding incompatible with operation.
Raised by get() when a field doesn't have EXACT encoding, which is required for deterministic exact lookups.
Example
user = table.query(schema).get(bio="machine learning") EncodingMismatchError: Field 'bio' has SEMANTIC encoding, get() requires EXACT
SlotSearchNotSupportedError¶
Raised when slot-specific search is attempted on Table/Bundle schemas.
from hybi.compose.errors import SlotSearchNotSupportedError
try:
# Table uses search-optimized encoding - cannot isolate slots
results = hb.query("users", schema).search("engineer", slot="department")
except SlotSearchNotSupportedError as e:
print(f"Schema type: {e.schema_type}")
print(f"Use search() without slot, or filter() for exact matches")
hybi.compose.SlotSearchNotSupportedError
¶
Bases: HyperBinderError
Slot-specific search not supported for this schema type.
Raised when attempting to use search(slot=...) on a Table or Record schema. These schemas use bundle encoding which combines all fields into a single vector, making it impossible to isolate individual slot contributions.
Example
table.query(schema).search("engineering", slot="department") SlotSearchNotSupportedError: Slot-specific search not supported for Table
DuplicateKeyError¶
Raised when primary key already exists during ingestion.
from hybi.compose.errors import DuplicateKeyError
try:
hb.ingest(df, collection="users", schema=schema)
except DuplicateKeyError as e:
print(f"Duplicate key '{e.key_field}': {e.duplicate_values}")
hybi.compose.DuplicateKeyError
¶
Bases: HyperBinderError
Primary key already exists in collection.
Raised during ingestion when attempting to insert a row with a primary key value that already exists in the collection.
Example
hb.ingest(df_with_duplicate_pk, collection="users", schema=schema) DuplicateKeyError: Duplicate primary key 'user_id': value 'U123' already exists
Intersection Errors¶
These errors relate to cross-collection join operations.
IntersectionError¶
Base exception for all intersection operations.
from hybi.compose.intersections import IntersectionError
try:
results = hb.query("employees").join("projects")
except IntersectionError as e:
print(f"Join failed: {e}")
hybi.compose.intersections.IntersectionError
¶
Bases: Exception
Base exception for intersection operations.
NoIntersectionError¶
Raised when no intersection is declared between collections.
from hybi.compose.intersections import NoIntersectionError
try:
results = hb.query("employees").join("projects")
except NoIntersectionError as e:
print(f"No intersection between '{e.source_collection}' and '{e.target_collection}'")
print(f"Collections connected to source: {e.existing_from_source}")
# Fix: hb.intersect("employees.<field>", "projects.<field>")
hybi.compose.intersections.NoIntersectionError
¶
InvalidIntersectionError¶
Raised when an intersection declaration is invalid.
from hybi.compose.intersections import InvalidIntersectionError
try:
hb.intersect("invalid_format", "also_invalid")
except InvalidIntersectionError as e:
print(f"Invalid intersection: {e}")
print(f"Field: {e.field}") # Which field caused the error
hybi.compose.intersections.InvalidIntersectionError
¶
AmbiguousIntersectionError¶
Raised when multiple intersections exist between collections.
from hybi.compose.intersections import AmbiguousIntersectionError
try:
results = hb.query("employees").join("projects")
except AmbiguousIntersectionError as e:
print(f"Found {e.count} intersections")
for ix in e.intersections:
print(f" {ix.source_field} -> {ix.target_field}")
# Fix: .join("projects", on=("employee_id", "assigned_to"))
hybi.compose.intersections.AmbiguousIntersectionError
¶
CircularJoinError¶
Raised when a join chain would create a cycle.
from hybi.compose.intersections import CircularJoinError
try:
results = (
hb.query("A")
.join("B")
.join("C")
.join("A") # Circular!
)
except CircularJoinError as e:
print(f"Circular join to '{e.collection}'")
print(f"Visited: {e.visited}") # ['A', 'B', 'C']
hybi.compose.intersections.CircularJoinError
¶
MaxJoinDepthError¶
Raised when join chain exceeds maximum allowed depth.
from hybi.compose.intersections import MaxJoinDepthError, JoinConfig
try:
results = hb.query("A").join("B").join("C").join("D").join("E").join("F")
except MaxJoinDepthError as e:
print(f"Exceeded depth {e.max_depth}")
print(f"Current depth: {e.current_depth}")
# Fix: Increase limit or simplify query
# hb = HyperBinder(join_config=JoinConfig(max_join_depth=10))
hybi.compose.intersections.MaxJoinDepthError
¶
QueryStateError¶
Raised when a query operation is called in an invalid state.
from hybi.compose.intersections import QueryStateError
try:
# Invalid: search() after join() is not supported
results = hb.query("employees").join("projects").search("urgent")
except QueryStateError as e:
print(f"Invalid query state: {e}")
hybi.compose.intersections.QueryStateError
¶
Error Handling Example¶
from hybi import (
HyperBinder,
HyperBinderError,
CollectionNotFoundError,
AuthenticationError,
)
from hybi.compose.errors import (
SchemaError,
SlotError,
NotFoundError,
)
from hybi.compose.intersections import (
NoIntersectionError,
CircularJoinError,
)
try:
hb = HyperBinder()
# Query operations
results = (
hb.query("employees", schema)
.find(department="Engineering")
.join("projects")
)
except CollectionNotFoundError as e:
print(f"Collection not found: {e}")
print(f"Suggestion: {e.suggestion}")
except SlotError as e:
print(f"Invalid field '{e.slot}'")
print(f"Valid fields: {e.valid_slots}")
except NoIntersectionError as e:
print(f"No intersection declared")
print(f"Fix: hb.intersect('{e.source_collection}.<field>', '{e.target_collection}.<field>')")
except CircularJoinError as e:
print(f"Circular join detected: {e.visited}")
except NotFoundError as e:
print(f"No row found: {e.conditions}")
except AuthenticationError as e:
print(f"Authentication failed: {e}")
except HyperBinderError as e:
print(f"Error [{e.error_code}]: {e}")
if e.details:
print(f"Details: {e.details}")