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
- Define (or reuse) an error variant
ClientError::MalformedInvite(String) with a descriptive reason.
- Replace
.unwrap_or_else(|_| Uuid::new_v4()) with ? propagation that returns ClientError::MalformedInvite(format!("invalid server_id: {e}")).
- 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.
- 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(_))));
}
Parent: #108
Problem
crates/client/src/joining.rs:68-69:And
crates/client/src/joining.rs:76:If the invite carries a non-parseable
server_idorcreate_channelfails, 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
ClientError::MalformedInvite(String)with a descriptive reason..unwrap_or_else(|_| Uuid::new_v4())with?propagation that returnsClientError::MalformedInvite(format!("invalid server_id: {e}")).create_channelcall — 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.crates/client/src/for otherunwrap_or_else(|_| Uuid::new_v4())orunwrap_or_default()patterns on parsed IDs and fix them too.Test
Add a test to
crates/client/src/lib.rstest module: