Skip to content

Commit 63de33e

Browse files
graph: phase 2 PR review fixes
Three real bugs surfaced by review: - compiled.py: _step_subgraph_node now wraps raw exceptions escaping the parent's middleware chain as NodeException with recoverable_state, matching _step_function_node. Previously a middleware-raised exception around a SubgraphNode dispatch escaped uncaught. - test_pipeline_utilities.py: the determinism re-run path (run_count > 1) now passes the clock stub when re-translating middleware. Was dropping it, so a future fixture combining determinism with TimingMiddleware would silently use real time.monotonic on subsequent runs. - test_pipeline_utilities.py: the subgraph middleware translation path now also passes the clock stub. Same omission as the determinism path — affects any future fixture combining a subgraph with TimingMiddleware. No current fixture exercises the latter two combinations; fix is defensive so the harness faithfully translates fixture intent.
1 parent 15c7298 commit 63de33e

2 files changed

Lines changed: 13 additions & 3 deletions

File tree

src/openarmature/graph/compiled.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -443,7 +443,17 @@ async def innermost(s: Any) -> Mapping[str, Any]:
443443
innermost,
444444
)
445445

446-
final_partial = await chain(state)
446+
try:
447+
final_partial = await chain(state)
448+
except RuntimeGraphError:
449+
raise
450+
except Exception as e:
451+
# Same wrap as _step_function_node: a raw exception escaping
452+
# the parent's middleware chain (e.g., a middleware bug or a
453+
# projection error) becomes NodeException tagged with the
454+
# SubgraphNode's wrapper name so §4 recoverable_state is
455+
# preserved.
456+
raise NodeException(node_name=current, cause=e, recoverable_state=state) from e
447457
return _merge_partial(state, final_partial, self.reducers, current)
448458

449459
@staticmethod

tests/conformance/test_pipeline_utilities.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -331,7 +331,7 @@ async def _run_one(spec: Mapping[str, Any], monkeypatch: pytest.MonkeyPatch) ->
331331
if "subgraph" in spec:
332332
sub_spec = spec["subgraph"]
333333
sub_sinks = sinks # same sinks; subgraph middleware shares the harness's lists
334-
sub_graph_mw, sub_node_mw = _translate_middleware_block(sub_spec.get("middleware"), sub_sinks)
334+
sub_graph_mw, sub_node_mw = _translate_middleware_block(sub_spec.get("middleware"), sub_sinks, clock)
335335
sub_built = build_graph(
336336
sub_spec,
337337
model_name=f"{sub_spec['name'].title()}State",
@@ -382,7 +382,7 @@ async def _run_one(spec: Mapping[str, Any], monkeypatch: pytest.MonkeyPatch) ->
382382
run_graph_mw, run_node_mw = (
383383
(graph_mw, node_mw)
384384
if run_count == 1
385-
else _translate_middleware_block(spec.get("middleware"), run_sinks)
385+
else _translate_middleware_block(spec.get("middleware"), run_sinks, clock)
386386
)
387387
run_built = build_graph(
388388
spec,

0 commit comments

Comments
 (0)