The wire error object for an expression failure: what
docs/wire-format.md documents as an event object's error key.
This is the only caller of Statifier.Parser.Location.resolve_span/4
in this repo (ADR-0002 - never reimplement the engine's span composition
locally). Every span this module emits, and every location it composes
from one, follows that helper's convention: both the predicator span's
end and the returned location's end are exclusive.
resolve_span/4 degrades rather than raising - a position past the end
of the value clamps to the value location's end, and a raw/expanded
desync returns the value location whole - so this module never rescues
it. Per project convention (CLAUDE.md, "errors are values / never
rescue-to-default at a leaf"), a call that could fail is not the shape
the failure takes here: the helper's own degraded return already is the
fallback.
A nil value location or a nil span means there is nothing to resolve.
anchor/3 never calls resolve_span/4 in either case - it returns
{:node, _} instead, so object/4 falls back to the owning node's own
span. That branch is this module deciding not to call the helper, which
is a different thing from catching what it raises.
location_kind reports what the producer did, not what the helper decided
"resolved" means resolve_span/4 was called with a value location and
a span. "node" means it was not (no span, or no value location) and the
owning node's own span was emitted instead. This module never inspects
the result to guess which happened - resolve_span/4's own degraded
return (falling back to the value location whole) is indistinguishable
from a genuine resolution by looking at the location alone, and modeling
that distinction here would be exactly the ADR-0002 failure this module
exists to prevent. So "resolved" may still span the whole attribute
value when the helper degraded internally.
Summary
Functions
Where to anchor error's span for origin: the value location of the
failing expression ({:value, _}, resolved against error.span by the
caller), the owning node's own span with nothing further to resolve
({:node, _}), or nothing at all (:none).
The wire error object for error, raised with cause origin.
Functions
@spec anchor( Statifier.Event.Cause.origin() | nil, Statifier.Machine.t(), Statifier.Evaluator.Error.t() ) :: {:value, Statifier.Parser.Location.t()} | {:node, Statifier.Parser.Location.t()} | :none
Where to anchor error's span for origin: the value location of the
failing expression ({:value, _}, resolved against error.span by the
caller), the owning node's own span with nothing further to resolve
({:node, _}), or nothing at all (:none).
Dispatches on origin and, for content, on the content struct itself -
never on a generic Map.get(node, :location) || Map.get(node, :node_location)
reflection, the same posture StatifierUI.Trace.Manifest.content_location/1
takes and for the same reason: that fallback is silently wrong for
Statifier.Machine.Content.Assign, whose :location is a path-expression
string, not a span.
A candidate value location is only ever returned as {:value, _} when
error.span is non-nil - a nil span means resolve_span/4 would not be
called, so the caller must not be handed a location that invites it.
@spec object( Statifier.Evaluator.Error.t(), Statifier.Event.Cause.origin() | nil, Statifier.Machine.t() | nil, String.t() | nil ) :: map()
The wire error object for error, raised with cause origin.
"kind" and "expression" are always present. "span" is present only
when error.span is non-nil. "location"/"location_kind" are present
only when both machine and source are supplied and anchor/3 finds
a location to anchor on - origin of nil, machine/source of nil,
or an origin anchor/3 cannot resolve at all all omit both keys, key
absence being the ADR-0005 discipline for "nothing here" rather than a
null or a sentinel.