Skip to content

Make dictyon's top-level error facade real or remove it #130

Description

@forkwright

Finding

dictyon::error::DictyonError is documented as the unified error returned by the crate's public async API, but no public function or method returns it. The live API exposes WireError, ControlError, NoiseError, and TransportError directly, while DictyonError exists only as a public enum plus three unused From conversions.

The crate therefore advertises a stable top-level error boundary that has no consumer and provides no actual abstraction.

Verified against main 9aa9a56223afdd47d7723104cd16a5c07d5fc722.

Evidence

  • crates/dictyon/src/error.rs:1-17 says DictyonError “is the error type returned by the public async API” and defines it as the unified wrapper for wire, control, and Noise errors.
  • error.rs:40-56 implements conversions from those three layer errors.
  • A repository-wide source inventory finds DictyonError only in that file's documentation, definition, and conversion impls. There is no construction or return site.
  • crates/dictyon/src/lib.rs:27-33 exposes pub mod error alongside all implementation modules rather than re-exporting one high-level facade.
  • Public control operations in crates/dictyon/src/control/mod.rs return ControlError; public connection operations in crates/dictyon/src/wire/mod.rs return WireError; Noise and skeleton transport APIs expose their own errors directly.
  • The unused facade does not currently absorb TransportError, even though the crate also publicly exposes that fourth layer error.
  • Phase 3 audit: missing PeersChangedPatch + Node fields, no zstd, transport duplication, no tracing, no map-stream integration test #20 owns consolidation of the parallel transport/API topology. This finding is narrower: whichever public topology survives must have a truthful error contract rather than retaining an unused nominal facade.

Why this matters

Public error types are part of a Rust library's compatibility and recovery contract. A downstream consumer reading the module documentation can reasonably design around one non-exhaustive DictyonError, only to discover that every operation requires separate error handling and no returned value can be matched as documented.

Keeping the facade “for later” also creates double maintenance. Every new layer error or semantic state requires a decision in the real API and a second decision in an enum nothing uses, with no compiler path proving the two stay aligned.

This is polished dead API rather than harmless private scaffolding: it is public, documented, non-exhaustive, and framed as the canonical caller surface.

Desired correction

Decide the public error boundary together with the transport/API convergence owned by #20:

  1. Make it real: expose a high-level client/facade whose public async operations return DictyonError, give each retained lower-layer error one deliberate conversion, and document when callers should use the high-level versus layer-specific APIs; or
  2. Remove it: delete DictyonError, its conversions, and the claim that the crate has a unified returned error until a real facade requires one.

Do not keep a public wrapper solely as a future marker.

Done when:

  • every public documentation claim names the error type the function actually returns;
  • DictyonError either has production return/construction sites across the intended facade or no longer exists;
  • retained variants cover exactly the errors reachable through that facade;
  • lower-level modules remain directly usable only where their separate contracts are intentional; and
  • tests demonstrate caller matching/conversion behavior for the chosen public boundary.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugUnintended behavior or production defect

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions