Exceptions Module
The exceptions module defines all custom exceptions raised by TreeStore.
Exception Hierarchy
graph TB
subgraph "Exception Hierarchy"
BASE[TreeStoreError<br/>Base exception]
IC[InvalidChildError<br/>Invalid child tag]
IP[InvalidParentError<br/>Invalid parent context]
MC[MissingChildError<br/>Missing mandatory child]
TMC[TooManyChildrenError<br/>Cardinality exceeded]
BASE --> IC
BASE --> IP
BASE --> MC
BASE --> TMC
end
TreeStoreError
- exception genro_treestore.TreeStoreError[source]
Bases:
ExceptionBase exception for all TreeStore errors.
This is the root exception class for the TreeStore library. All specific exceptions inherit from this class, allowing callers to catch any TreeStore error with:
try: # TreeStore operations except TreeStoreError as e: # Handle any TreeStore error
- args
Standard exception arguments containing the error message.
Base exception for all TreeStore errors. Catch this to handle any TreeStore-specific exception.
from genro_treestore import TreeStore, TreeStoreError
try:
store = TreeStore(builder=my_builder)
store.invalid_tag()
except TreeStoreError as e:
print(f"TreeStore error: {e}")
InvalidChildError
- exception genro_treestore.InvalidChildError[source]
Bases:
TreeStoreErrorRaised when a child tag is not allowed under the current parent.
This exception is raised when attempting to add a child node with a tag that violates the builder’s structural rules. Common causes:
Adding a child to a void/leaf element (e.g., children under <br>)
Tag not in the parent’s allowed children list
Tag explicitly excluded from the parent
Example
>>> store = TreeStore(builder=HtmlBuilder(), raise_on_error=True) >>> ul = store.body().ul() >>> ul.div() # div is not a valid child of ul InvalidChildError: 'div' is not a valid child of 'ul'
See also
element()
Raised when attempting to add a child that is not allowed by the builder’s validation rules.
from genro_treestore import TreeStore, InvalidChildError
from genro_treestore.builders import HtmlBuilder
store = TreeStore(builder=HtmlBuilder())
ul = store.ul()
try:
ul.div() # div is not a valid child of ul
except InvalidChildError as e:
print(f"Invalid child: {e}")
# InvalidChildError: 'div' is not a valid child of 'ul'
InvalidParentError
- exception genro_treestore.InvalidParentError[source]
Bases:
TreeStoreErrorRaised when a node is placed under an invalid parent type.
This exception is raised when a tag requires a specific parent type but is being added to a different parent. This is the inverse of InvalidChildError - it validates from the child’s perspective rather than the parent’s.
Common use cases:
<li> elements must be children of <ul>, <ol>, or <menu>
<td>/<th> elements must be children of <tr>
<option> elements must be children of <select> or <datalist>
Example
>>> store = TreeStore(builder=HtmlBuilder(), raise_on_error=True) >>> div = store.body().div() >>> div.td() # td must be child of tr InvalidParentError: 'td' cannot be child of 'div', requires 'tr'
See also
element()
Raised when a tag is added in an invalid parent context.
from genro_treestore import TreeStore, InvalidParentError
store = TreeStore(builder=my_builder)
try:
store.body() # body may only be child of html
except InvalidParentError as e:
print(f"Invalid parent: {e}")
MissingChildError
- exception genro_treestore.MissingChildError[source]
Bases:
TreeStoreErrorRaised when a required child tag is missing from a parent.
This exception is raised during validation when a parent node is missing one or more mandatory children as defined by the builder’s cardinality rules (minimum count > 0).
The error is typically raised when:
Calling
store.builder.check()explicitlyUsing ValidationSubscriber with hard error mode
Finalizing a structure that requires certain children
Example
>>> # Assuming a builder requires 'head' and 'body' in 'html' >>> store = TreeStore(builder=HtmlBuilder()) >>> html = store.html() >>> # Missing head and body children >>> store.builder.check(html) MissingChildError: 'html' requires child 'head' (min: 1, found: 0)
See also
check()ValidationSubscriber
Raised when a mandatory child element is missing during validation.
from genro_treestore import TreeStore, MissingChildError
from genro_treestore.builders import BuilderBase, element
class DocBuilder(BuilderBase):
@element(children='title[1]') # title is required
def section(self, target, tag, **attr):
return self.child(target, tag, **attr)
@element()
def title(self, target, tag, value=None, **attr):
return self.child(target, tag, value=value, **attr)
store = TreeStore(builder=DocBuilder())
sec = store.section()
# During validation, if title is missing:
# MissingChildError: 'section' requires at least 1 'title' child
TooManyChildrenError
- exception genro_treestore.TooManyChildrenError[source]
Bases:
TreeStoreErrorRaised when a child tag exceeds its maximum allowed count.
This exception is raised when adding a child would exceed the maximum cardinality defined by the builder’s rules. For example, an HTML document can only have one <head> element.
Cardinality is specified using slice notation in builder definitions:
tagortag[:]- unlimited (0 to infinity)tag[1]- exactly one requiredtag[0:1]- zero or one (optional, max 1)tag[1:3]- between 1 and 3 inclusive
Example
>>> # Assuming 'head' has max cardinality of 1 >>> store = TreeStore(builder=HtmlBuilder(), raise_on_error=True) >>> html = store.html() >>> html.head() # First head - OK >>> html.head() # Second head - Error TooManyChildrenError: 'html' already has maximum 'head' children (1)
See also
element()_parse_children_spec()
Raised when adding a child would exceed the maximum cardinality.
from genro_treestore import TreeStore, TooManyChildrenError
from genro_treestore.builders import BuilderBase, element
class DocBuilder(BuilderBase):
@element(children='title[1]') # exactly one title
def section(self, target, tag, **attr):
return self.child(target, tag, **attr)
@element()
def title(self, target, tag, value=None, **attr):
return self.child(target, tag, value=value, **attr)
store = TreeStore(builder=DocBuilder())
sec = store.section()
sec.title(value='First Title')
try:
sec.title(value='Second Title') # exceeds limit
except TooManyChildrenError as e:
print(f"Too many: {e}")
# TooManyChildrenError: 'section' allows at most 1 'title' child
Exception Handling Patterns
Catching All TreeStore Errors
from genro_treestore import TreeStoreError
try:
# Any TreeStore operation
store.some_operation()
except TreeStoreError as e:
logger.error(f"TreeStore operation failed: {e}")
Specific Exception Handling
from genro_treestore import (
InvalidChildError,
MissingChildError,
TooManyChildrenError,
)
try:
store.build_structure()
except InvalidChildError as e:
print(f"Invalid structure: {e}")
except MissingChildError as e:
print(f"Missing required element: {e}")
except TooManyChildrenError as e:
print(f"Too many elements: {e}")
Exception Flow
flowchart TD
OP[Operation]
CHK{Validation<br/>Check}
OK[Success]
IC[InvalidChildError]
MC[MissingChildError]
TMC[TooManyChildrenError]
OP --> CHK
CHK -->|Valid child| OK
CHK -->|Unknown tag| IC
CHK -->|Missing required| MC
CHK -->|Exceeds max| TMC
See Also
Validation Guide - Validation rules and cardinality
Builders Guide - Creating builders with validation