Summary
Error propagation in this codebase does not use VBA's error mechanism. Only 16 handlers out of 3,774 re-raise. About 74% write the message into an object field — m_Error, p_Error, Me.Error — and return normally; the caller then checks that field.
Err.Raise 1000 (5,152 sites, always the same literal) unwinds one frame, and the guard If Err.Number <> 1000 in the handler means "an inner procedure already wrote a human-readable message — do not overwrite it." It is a hand-rolled exception chain built on one magic number.
So the error flow is module-variable data flow, which the module-variable task already models. This change only has to label it.
Depends on
T9 (module-level variable nodes with read/write references) in docs/vba-node-discovery-plan.md. Do not start before T9 merges.
Proposed fix
- Config knob
vba.errorChannel: an array of variable-name patterns, defaulting to ["m_Error", "p_Error", "g_Error", "Error"]. Threaded through VbaExtractionOptions. Same validation shape as vba.sqlWrappers; no user-supplied regex — this runs per line.
- When a read or write reference targets a matching variable, set
metadata.errorChannel: true alongside the existing property-get / property-set kind.
- Nothing else. No new edge kind. The chain
procedure --property-set(errorChannel)--> m_Error --property-get(errorChannel)--> caller already exists once T9 has landed.
End-to-end requirement
Verify on a real class that inner procedure writes channel -> outer procedure reads channel -> form displays it is traversable. A one-hop version is the half-bridged flow CLAUDE.md forbids — if the second hop does not connect, the task is not done.
Acceptance criteria
Context
Task E4 of docs/vba-error-handling-plan.md.
Summary
Error propagation in this codebase does not use VBA's error mechanism. Only 16 handlers out of 3,774 re-raise. About 74% write the message into an object field —
m_Error,p_Error,Me.Error— and return normally; the caller then checks that field.Err.Raise 1000(5,152 sites, always the same literal) unwinds one frame, and the guardIf Err.Number <> 1000in the handler means "an inner procedure already wrote a human-readable message — do not overwrite it." It is a hand-rolled exception chain built on one magic number.So the error flow is module-variable data flow, which the module-variable task already models. This change only has to label it.
Depends on
T9 (module-level
variablenodes with read/write references) indocs/vba-node-discovery-plan.md. Do not start before T9 merges.Proposed fix
vba.errorChannel: an array of variable-name patterns, defaulting to["m_Error", "p_Error", "g_Error", "Error"]. Threaded throughVbaExtractionOptions. Same validation shape asvba.sqlWrappers; no user-supplied regex — this runs per line.metadata.errorChannel: truealongside the existingproperty-get/property-setkind.procedure --property-set(errorChannel)--> m_Error --property-get(errorChannel)--> calleralready exists once T9 has landed.End-to-end requirement
Verify on a real class that
inner procedure writes channel -> outer procedure reads channel -> form displays itis traversable. A one-hop version is the half-bridged flowCLAUDE.mdforbids — if the second hop does not connect, the task is not done.Acceptance criteria
m_Error = "x"inside a handler ->property-set,errorChannel: true,inErrorHandler: trueIf m_Error <> "" Thenin a caller ->property-get,errorChannel: trueErrorCountdoes not match (the pattern is a name, not a substring)vba.errorChannel: ["lastFailure"]matches that name and keeps the defaultsRiesgo.cls/Edicion.cls/ExpedienteOperaciones.cls, every channel-writing handler produces a flagged reference, and at least one complete write -> read -> display chain is traversable; show it in the PR bodyContext
Task E4 of
docs/vba-error-handling-plan.md.