BE-4067 whole-mando error unwalling
BE-4067 FINISHED the mando error-stack “unwalling” that BE-4047 began: it removed ALL remaining production raw error_stack::Report<C> from mando-lib and adopted the full BE-4000 devex idiom (#[mando_error] + #[cause(...)] + bare ?) everywhere. The walls that BE-3657 error_stack Adoption phase 3 documented as structurally frozen are now gone.
For Agents
Branch
feature/BE-4067@0dff4f2d, stacked onfeature/BE-4047(!599). 9 commits, one per subsystem. GOAL ACHIEVED: zero production raw-Report inmando-lib. Final whole-branch review verdict: READY-TO-MERGE, no findings. Gates: lib 376/0,clippy --all-featuresclean, no cross-crate ripple. Spec + plan (untracked):docs/superpowers/specs/2026-08-04-be4067-whole-mando-unwalling-design.md+docs/superpowers/plans/2026-08-04-be4067-whole-mando-unwalling.md.
What “unwalled” means (goal achieved)
Zero production raw-Report in mando-lib, verified three ways:
git grep into_mando_result -- mando-lib/src= 0 (the tower-edge lift verb has no remaining production call site).- The ONLY production
into_report().into_inner()left is the intentional body of the sharedwrap_http_callhelper. - Zero raw-
Report-returning production fns remain.
This closes the “walled service towers” finding from BE-3657 error_stack Adoption phase 3: the seven flat-typed towers that made cross-crate Report flow “structurally impossible” are all restructured; Reports now flow to the step boundary through the native MandoReport idiom.
The 9 commits (one per subsystem)
| # | Commit | Subsystem |
|---|---|---|
| 1 | b6086f79 | wrap_http_call helper (the new shared pattern, see below) |
| 2 | 52205518 | fingrid |
| 3 | 23da1335 | data_platform |
| 4 | 9346d7c9 | metis |
| 5 | cc638039 | ebs |
| 6 | 92c6da5f | opl report_polars born-lift |
| 7 | fa1b1fa2 | ems service tower |
| 8 | 78c567e6 | atp (delete VolueAtpAuthenticationProviderError) |
| 9 | 0dff4f2d | fingrid into_mando_result cleanup (branch tip) |
The new pattern: wrap_http_call
The one genuinely new artifact worth recording. In mando-lib/src/adapter/http_cause.rs:
#[track_caller]
fn wrap_http_call<E, F>(source: HttpCallError, make: F) -> MandoReport<E>Why a helper and NOT a
#[cause]macro route
wrap_http_callis a shared helper, not a#[cause]message-only route. It replaced the triplicatedHttpCallError -> ApiErrorwrap at metis / fingrid / ems. A#[cause(...)]route is message-only, butApiErroris multi-field (it carries a source) AND re-attaches an opaqueHttpContext- a#[cause]route would DROP both. The helper preserves them.
Must keep
#[track_caller]
wrap_http_callMUST retain#[track_caller]so the caller’s file/line survives into emission. Dropping it silently degrades every wrapped HTTP error’s location back to the helper body (the same#[track_caller]-loss trap that bit the earliermap_err(fn-pointer)migrations).
The recipe: BE-4047’s a/b/c + step (d)
BE-4067 extends the BE-4047 conversion recipe with a fourth step:
- (d) message-only foreign-error maps become
#[cause(ForeignErr)]+ bare?.
KEEP manual construction (do NOT collapse to #[cause]) for:
- Multi-field variants:
NonSuccessStatus,InvalidUrl,CannotParseJson(they carry structured fields). - Context-prefixed / multi-source maps: ebs
SambaError, data_platformSdkError(they prepend context or fold several sources).
The dividing line is the same as wrap_http_call’s rationale: a #[cause] route only carries a message, so anything with fields or attached context stays hand-constructed.
ems SERVICE tower gotcha
Associated
Errortype isE, notResultThe step-service tower’s
type Error = Report<VolueEmsError>becomestype Error = MandoReport<VolueEmsError>- NOTMandoResult<..>. TheFlowStepService::Errorassociated type IS the error typeE, never the result alias. Getting this wrong is the easy mistake here.
Location note: the ems service tower lives under service/volue/ems/* (the SERVICE layer), not under adapter/. The adapter-layer ems changes are separate.
atp: deleted VolueAtpAuthenticationProviderError
Commit 78c567e6 DELETES the VolueAtpAuthenticationProviderError enum outright as part of unwalling atp. The knock-on: new()’s error signature changed, but there was no cross-crate ripple - the change is absorbed by an anyhow ? at mando-bess/src/lib.rs:198 (the init path is anyhow-typed, so the tightened error type just flows through).
Emission preserved (BE-4014 harness)
Emission fidelity is pinned per-subsystem via Datadog goldens using the BE-4014 Datadog Error-Rendering Test Harness. Goldens are location-trimmed (volatile file/line omitted so the subset matcher ignores them). 11 dd_emission tests pass - the unwalling is a refactor, not a behavior change, and the goldens prove it.
Gates + review
- Final whole-branch review: READY-TO-MERGE, no findings.
- lib gate: 376 passed / 0 failed.
cargo clippy --all-features: clean.- No cross-crate ripple (atp’s
new()error change absorbed by theanyhow ?atmando-bess/src/lib.rs:198).
North-star context
BE-4067 is the mando-ERRORS axis of the larger conformance goal (conformant traces AND errors across all BESS services). Still-open children:
- mando trace / instrumentation conformance (the trace axis, not touched here).
- error + trace conformance in
bess-optimization/bess-forecast-day-ahead/ the dashboards (downstream services). - Phase 4
#[error_meta](per-variant metadata: event type, resolution step, business message, description). - The not-yet-landed
error.tracefield +.step_context()helper (the two redesign pieces that never landed on develop).
graph LR A["BE-3657<br/>error_stack adoption"] --> B["BE-4000<br/>#[mando_error] derive"] B --> C["BE-4047<br/>unwalling begun"] C --> D["<b>BE-4067</b><br/>unwalling FINISHED<br/>zero raw-Report in mando-lib"] D --> E["still open:<br/>trace conformance,<br/>downstream services,<br/>phase 4 #[error_meta]"] style D fill:#264653,stroke:#2a9d8f,color:#fff style E fill:#3d2020,stroke:#a55,color:#fff
Related
- BE-4067 error DX clarity - the grammar-clarity + mando-bess-lib adoption follow-on, stacked directly on this branch’s tip: renames
#[cause]→#[reframe]/#[chain]/#[transparent], makesMandoReportopaque, and adopts the 25 mando-bess-lib service enums into the error system (a DD telemetry change on the financial flows) - BE-4047 - the unwalling phase this FINISHES; BE-4067 is stacked directly on it (!599)
- BE-4000 derive transplant - the
#[mando_error]/#[cause(...)]/ bare-?devex idiom BE-4067 adopts everywhere - BE-3657 error_stack Adoption - master error-stack trail; its phase-3 “walled towers” finding is what BE-4067 dismantles
- BE-4014 Datadog Error-Rendering Test Harness - the DD golden harness pinning per-subsystem emission fidelity (11
dd_emissiontests) - Agent Context