Error projection
Frond errors are cause chains. The outer error says where the runtime boundary failed: readiness, operation, dependency, live work, invalid graph, or unavailable runtime. The inner frames carry the domain failure that actually happened.
That shape is useful inside the runtime, but poor as a reporting object. If every failed action reports as ActionFailed, every failed refresh reports as RefreshFailed, or every boundary read reports as a generic runtime wrapper, your tracker groups different production failures together. The opposite problem also happens: reporting tools usually keep only a shallow cause chain, so the actual driver error can disappear behind Frond’s wrappers.
Projection turns the full Frond failure into a reportable error.
What projection does
Frond.Diagnostics.projectError(error) serializes the cause chain, skips known Frond wrapper frames, and chooses the meaningful root frame. A server 500 thrown from acquire should report as that server/domain failure, not merely as AcquireFailed or Operation failed.
const projection = Frond.Diagnostics.projectError(error);
projection.headline; // "Readiness failed", "Operation failed", ...
projection.rootTag; // the selected root frame
projection.rootMessage; // the root message
projection.nodeId; // graph context, when available
projection.causeChain; // serialized full chain
Frond.Diagnostics.createErrorReport(error) wraps that projection for reporting:
const report = Frond.Diagnostics.createErrorReport(error);
report.error; // Error passed to the tracker
report.fingerprint; // grouping key
report.tags; // node, kind, operation context
report.contexts; // frond summary + full cause chain
report.extra; // safe raw preview
The report keeps the graph context without letting the graph wrapper become the only visible error.
Why not report the thrown error directly
The thrown value is still the correct control-flow value. React boundaries, ensureReady(), and action calls should receive the runtime failure as-is because it carries retry and graph context.
Reporting is a different boundary. A tracker needs:
- a stable fingerprint that separates unrelated failures
- a visible root cause
- node id, tag, dependency, and operation context
- the full cause chain as structured context, not as a best-effort nested
cause
Projection is the handoff between those two boundaries.
Where to use it
Use projectError or createErrorReport when a failure leaves Frond and enters UI display, logging, or a tracker.
| Surface | Use |
|---|---|
| Runtime sink | Frond.Diagnostics.createRuntimeReportSink(...) |
| One-off diagnostic | Frond.Diagnostics.createErrorReport(error) |
| React error boundary | FrondReact.getErrorReport(error) |
| Operation failure state | Frond.Diagnostics.createErrorReport(operationFailure.error) |
| Manual chain inspection | Frond.Diagnostics.serializeCauseChain(error) |
For Sentry, pass report.error, report.fingerprint, report.tags, report.contexts, and report.extra instead of the raw runtime wrapper. See Sentry projection.
Next: Tags and diagnostics — naming nodes and what shows up in devtools and logs.