Skip to content

Replace bare unwrap() with expect() in production code paths #76

@Dancode-188

Description

@Dancode-188

Background

This is a pre-publish polish task, not a bug fix. It is not blocking any current work and should be picked up during v0.3.0 release prep, before the crates.io publish.

Rust's .unwrap() panics with a generic message that gives no context at the call site. In library code, .expect("reason") is the right form: it panics with an explanation of the invariant that was violated, and that explanation appears directly in the panic output. When Pathweave panics inside a downstream application, the message is the first thing that developer sees. "PeerId is always 32 bytes" orients them; "called unwrap() on a None value" does not.

The rule is narrow: production code paths in library crates use .expect("invariant"), test code uses .unwrap() freely. No change is needed in #[cfg(test)] blocks or in pw-chat.

What needs to change

Three patterns exist in the production code paths across the library crates.

Mutex poison guards (pathweave-core/src/node.rs, pathweave-core/src/router.rs, pathweave-transport-quic/src/lib.rs):

// before
mutex.lock().unwrap()

// after
mutex.lock().expect("mutex not poisoned")

Fixed-size slice conversions (pathweave-transport-ble/src/lib.rs, lines 610, 636, 822, 922):

// before
let short_id: [u8; 8] = data[1..9].try_into().unwrap();
let short_id: [u8; 8] = identity.peer_id().as_bytes()[..8].try_into().unwrap();

// after
let short_id: [u8; 8] = data[1..9].try_into().expect("service data slice is always exactly 8 bytes");
let short_id: [u8; 8] = identity.peer_id().as_bytes()[..8].try_into().expect("PeerId is always 32 bytes");

Bundle reassembly entry removal (pathweave-core/src/bundle.rs, line 208):

// before
let complete = self.pending.remove(&seq).unwrap();

// after
let complete = self.pending.remove(&seq)
    .expect("entry was inserted above and is_complete() confirmed it");

Acceptance criteria

  • No .unwrap() calls remain in non-test production code in pathweave-core, pathweave-transport-quic, or pathweave-transport-ble
  • Every replacement uses .expect("specific invariant explanation"), not just .expect("")
  • #[cfg(test)] blocks and test helper functions are left unchanged
  • cargo test --workspace passes after the change

Out of scope

  • Changing error handling strategy beyond the mechanical unwrap-to-expect substitution
  • Adding #![deny(clippy::unwrap_used)] as a lint (can follow once the substitution is complete)
  • Any changes to pw-chat, which is a binary example and not a library crate

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions