Skip to content

[client] Propagate UUID parse errors during invite join instead of silently regenerating #115

@intendednull

Description

@intendednull

Parent: #108

Problem

crates/client/src/joining.rs:68-69:

server.id = willow_channel::ServerId(
    uuid::Uuid::parse_str(&server_id).unwrap_or_else(|_| uuid::Uuid::new_v4()),
);

And crates/client/src/joining.rs:76:

let ch_id = server
    .create_channel(name, willow_channel::ChannelKind::Text)
    .unwrap_or_else(|_| willow_channel::ChannelId::new());

If the invite carries a non-parseable server_id or create_channel fails, the joiner silently generates a fresh UUID and joins as if the invite were valid. The joiner now thinks they're in a different server from everyone else — a near-impossible-to-diagnose split-brain.

Fix

  1. Define (or reuse) an error variant ClientError::MalformedInvite(String) with a descriptive reason.
  2. Replace .unwrap_or_else(|_| Uuid::new_v4()) with ? propagation that returns ClientError::MalformedInvite(format!("invalid server_id: {e}")).
  3. Do the same for the create_channel call — failing to create a channel during invite acceptance should surface to the user, not silently create a new channel ID that no one else knows about.
  4. Grep crates/client/src/ for other unwrap_or_else(|_| Uuid::new_v4()) or unwrap_or_default() patterns on parsed IDs and fix them too.

Test

Add a test to crates/client/src/lib.rs test module:

#[tokio::test]
async fn malformed_invite_server_id_is_rejected() {
    let client = test_client();
    let bad_invite = InviteToken { server_id: "not-a-uuid".into(), /* ... */ };
    let result = client.accept_invite(bad_invite).await;
    assert!(matches!(result, Err(ClientError::MalformedInvite(_))));
}

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