Flows: fallible FlowNode impls (!void commands, !T reporters) — codegen error handling
Spun out of review on labelle-toolkit/labelle-assembler#239 (gemini-code-assist finding).
Problem
A FlowNode whose impl returns an error union — very common in Zig for fallible operations — does not codegen correctly:
!void command: CustomNode lowering emits a bare statement game_mod.PluginFlowNodes.<q>.impl(game, …); (flow-codegen/src/codegen.zig:~1730). For a !void impl that's an ignored error union → Zig compile error.
!T reporter: lowering emits const n<id>_value = …impl(game, …); binding an error union; downstream pins can't consume !T, and an unused/unwrapped error union won't compile.
Two halves
- Classification (assembler) —
!void should classify as a command (no output pin), not a reporter. Fixed in #239 for both discovery paths (flowNodeIsVoid in codegen/scan.zig and the editor-catalog inference in flow_catalog/discovery.zig), which previously checked exact "void" only.
- Codegen (this issue, flow-codegen) — decide and implement an error policy for fallible impls. Options: emit
try (propagate — requires the generated flow handler to be fallible, which event handlers currently are not), catch {} / catch |e| log, or reject fallible impls with a clear diagnostic until a policy lands. Applies to both the command path and the !T reporter path.
Acceptance
A FlowNode with a !void impl wired as a CustomNode compiles and runs; a !T reporter either compiles with a defined unwrap policy or is rejected with a clear error (not a raw Zig compile error). Parent: labelle-toolkit/labelle-gui#187.
Flows: fallible FlowNode impls (
!voidcommands,!Treporters) — codegen error handlingSpun out of review on labelle-toolkit/labelle-assembler#239 (gemini-code-assist finding).
Problem
A
FlowNodewhose impl returns an error union — very common in Zig for fallible operations — does not codegen correctly:!voidcommand: CustomNode lowering emits a bare statementgame_mod.PluginFlowNodes.<q>.impl(game, …);(flow-codegen/src/codegen.zig:~1730). For a!voidimpl that's an ignored error union → Zig compile error.!Treporter: lowering emitsconst n<id>_value = …impl(game, …);binding an error union; downstream pins can't consume!T, and an unused/unwrapped error union won't compile.Two halves
!voidshould classify as a command (no output pin), not a reporter. Fixed in #239 for both discovery paths (flowNodeIsVoidincodegen/scan.zigand the editor-catalog inference inflow_catalog/discovery.zig), which previously checked exact"void"only.try(propagate — requires the generated flow handler to be fallible, which event handlers currently are not),catch {}/catch |e| log, or reject fallible impls with a clear diagnostic until a policy lands. Applies to both the command path and the!Treporter path.Acceptance
A
FlowNodewith a!voidimpl wired as aCustomNodecompiles and runs; a!Treporter either compiles with a defined unwrap policy or is rejected with a clear error (not a raw Zig compile error). Parent: labelle-toolkit/labelle-gui#187.