v0 · Developer Preview Frond is under active development. APIs may change between releases.

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.

SurfaceUse
Runtime sinkFrond.Diagnostics.createRuntimeReportSink(...)
One-off diagnosticFrond.Diagnostics.createErrorReport(error)
React error boundaryFrondReact.getErrorReport(error)
Operation failure stateFrond.Diagnostics.createErrorReport(operationFailure.error)
Manual chain inspectionFrond.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.