X--Selkie--WidgetCycle
NAME
X::Selkie::WidgetCycle - thrown when a widget's parent chain loops back on itself
SYNOPSIS
use X::Selkie::WidgetCycle;
CATCH {
when X::Selkie::WidgetCycle {
note "widget tree is cyclic: {.chain}";
}
}DESCRIPTION
A Selkie widget tree is a tree by convention, not by construction: parent is a writable attribute that layout containers set when they adopt a child. One mis-ordered reparent ā a container adopting a widget that is already one of its own ancestors ā makes the "tree" cyclic, and every walk up a parent chain then runs forever.
Selkie's parent-chain walks all hop through Selkie::Tree's next-ancestor, which throws this exception once a single walk exceeds PARENT-CHAIN-LIMIT hops. Catching it is rarely useful: it is always an upstream bug in whatever set parent, and the whole point of throwing is that the alternative ā a render thread spinning on an endless chain, with a frozen screen and no keyboard ā is undiagnosable from the outside.
chain holds a bounded, human-readable rendering of the widgets involved (class name and widget-id, joined by arrows), which is normally enough to identify the offending container directly. hops is the budget that was exceeded.
SEE ALSO
Selkie::Tree ā
next-ancestor,PARENT-CHAIN-LIMIT, and the walk contractSelkie::Widget ā where
parentlives
class X::Selkie::WidgetCycle
Thrown when a parent-chain walk exceeds Selkie::Tree's PARENT-CHAIN-LIMIT, i.e. when the widget tree contains a cycle.
has Str $.chain
Bounded description of the widgets on the offending chain, as Class#id - Class#id -> ā¦>.
has Int $.hops
The hop budget that was exceeded.