The GitHub Actions job "CI" on tvm-ffi.git/structural-error-context has succeeded. Run started by GitHub user tqchen (triggered by tqchen).
Head commit for run: 172481800f7fd0d47a602246e78b258583510b76 / tqchen <[email protected]> [EXTRA][FEAT] StructuralErrorContext for structural-context-aware error reporting When code throws while recursively visiting an Object tree, the resulting error message lacks position context — the user sees what went wrong but not where in the tree. This change adds a typed payload to attach the visit chain to Error and resolve it to a structured access path. Recording is best-effort: callers are not required to instrument every node along the visit path. Whatever frames happen to be wrapped with BEGIN/END (or seeded by THROW) get recorded; FindAccessPaths then does a best-effort match of that sparse breadcrumb against the live tree. Missing intermediates are tolerated — sparse anchors still narrow the match, and allow_prefix_match=true reports the deepest reached prefix when the innermost frame is unreachable. Expected usage A visitor or checker instruments each visit level with BEGIN/END so each recursion frame records its node on rethrow. At the root of the visit, a try/catch retrieves the StructuralErrorContext and calls FindAccessPaths to resolve the recorded chain into AccessPaths usable for rich error reporting. void Visitor::Visit(const ObjectRef& node) { TVM_FFI_STRUCTURAL_VISIT_BEGIN(); DispatchVisitFields(node); TVM_FFI_STRUCTURAL_VISIT_END(node); } void Check(const ObjectRef& root) { try { visitor.Visit(root); } catch (Error& err) { auto sc = StructuralErrorContext::TryGetFromError(err); if (sc) { auto paths = StructuralErrorContext::FindAccessPaths(root, sc.value()); // paths describes WHERE in root the error fired, e.g. // Root -> Attr("body") -> ArrayItem(2) -> Attr("cond") -> Attr("lhs") // Use it to enrich the message with structured position info. } throw; } } TVM_FFI_STRUCTURAL_VISIT_THROW is the variant for cases where the bad spot is somewhere the surrounding BEGIN/END does not already record — typically a child field of the visited node, or a helper called from a visit that has no BEGIN/END of its own. It seeds the context with the given node as the innermost frame. void Visitor::VisitTPair(const ObjectRef& node) { TVM_FFI_STRUCTURAL_VISIT_BEGIN(); if (auto pair = node.as<TPair>()) { if (!IsValid(pair.value()->lhs)) { // Throw site pinned at .lhs (not at node) so the AccessPath // ends at .lhs. The surrounding END appends `node` next. TVM_FFI_STRUCTURAL_VISIT_THROW(ValueError, pair.value()->lhs) << "invalid lhs"; } } TVM_FFI_STRUCTURAL_VISIT_END(node); } FindAccessPaths walks root via reflection, normalizes the recorded pattern (drops nulls, collapses consecutive duplicates), and returns one or more AccessPaths whose innermost step points at the throw site. API - StructuralErrorContext: typed payload in tvm/ffi/extra/, with a mutable List<ObjectRef> reverse_visit_pattern (innermost-first breadcrumb trail) and an optional prev_error_context (preserved when wrapping a pre-existing payload in extra_context). - TVM_FFI_STRUCTURAL_VISIT_BEGIN / TVM_FFI_STRUCTURAL_VISIT_END(node): instrument visit dispatch. On rethrow, END appends node to the in-flight Error's StructuralErrorContext. - TVM_FFI_STRUCTURAL_VISIT_THROW(kind, node) << "msg": throw an Error with the StructuralErrorContext pre-attached; use when END would not already record the throw site. - StructuralErrorContext::FindAccessPaths(root, ctx, allow_prefix_match): walks root via reflection and returns Array<AccessPath> for matched positions. Best-effort match — does not require every visited node to be recorded. Strict full-match by default; allow_prefix_match=true reports the deepest prefix when the innermost frame is unreachable. - StructuralErrorContext::TryGetFromError(err): inline helper to fetch the payload from an Error, NullOpt if absent. ABI No ABI changes. Reuses the existing Error::extra_context slot via existing ObjectUnsafe patterns. Tests cover macro-builds-chain for both BEGIN/END and THROW variants, FindAccessPaths correctness (basic match, all access kinds, sparse anchors demonstrating best-effort match with missing intermediates, partial-chain prefix matching, edge cases including root-itself match, records cleanup for null and dup-consecutive), and TryGetFromError composition. Report URL: https://github.com/apache/tvm-ffi/actions/runs/25812346649 With regards, GitHub Actions via GitBox --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
