From 72daa3f510ea381b7e3606c75f03ce6000dc780c Mon Sep 17 00:00:00 2001 From: Owen Jacobson Date: Fri, 13 Sep 2024 02:22:57 -0400 Subject: Tolerate panics in channel::app where they can only be triggered by implementation errors. --- src/channel/app.rs | 49 +++++++++++++++++-------------------------------- 1 file changed, 17 insertions(+), 32 deletions(-) (limited to 'src/channel/app.rs') diff --git a/src/channel/app.rs b/src/channel/app.rs index adefa3e..c060b23 100644 --- a/src/channel/app.rs +++ b/src/channel/app.rs @@ -16,7 +16,7 @@ use super::repo::{ use crate::{ clock::DateTime, error::BoxedError, - login::repo::logins::{Id as LoginId, Login, Provider as _}, + login::repo::logins::{Login, Provider as _}, }; pub struct Channels<'a> { @@ -32,9 +32,9 @@ impl<'a> Channels<'a> { pub async fn create(&self, name: &str) -> Result<(), BoxedError> { let mut tx = self.db.begin().await?; let channel = tx.channels().create(name).await?; + self.broadcaster.register_channel(&channel); tx.commit().await?; - self.broadcaster.register_channel(&channel)?; Ok(()) } @@ -50,7 +50,7 @@ impl<'a> Channels<'a> { .messages() .create(&login.id, channel, body, sent_at) .await?; - let message = Message::from_login(login, message)?; + let message = Message::from_login(login, message); tx.commit().await?; self.broadcaster.broadcast(channel, message); @@ -122,33 +122,25 @@ impl Message { Ok(message) } - fn from_login(sender: &Login, message: StoredMessage) -> Result { - if sender.id != message.sender { - // This functionally can't happen, but the funny thing about "This - // can never happen" comments is that they're usually wrong. - return Err(MessageError::LoginMismatched { - sender: sender.id.clone(), - message: message.sender, - }); - } + fn from_login(sender: &Login, message: StoredMessage) -> Self { + // Panic as this logic is enforced by the caller anyways. This "can't + // happen," other than via programming mistakes, and cannot be fixed + // by config changes or changing user behaviours. + assert_eq!( + message.sender, sender.id, + "broadcast message must have the same sender ({}) as the stored message ({})", + sender.id, message.sender, + ); - let message = Self { + Self { sender: sender.clone(), id: message.id, body: message.body, sent_at: message.sent_at, - }; - - Ok(message) + } } } -#[derive(Debug, thiserror::Error)] -enum MessageError { - #[error("sender login id {sender} did not match message login id {message}")] - LoginMismatched { sender: LoginId, message: LoginId }, -} - // Clones will share the same senders collection. #[derive(Clone)] pub struct Broadcaster { @@ -181,16 +173,15 @@ impl Broadcaster { } } - pub fn register_channel(&self, channel: &ChannelId) -> Result<(), RegisterError> { + // panic: if ``channel`` is already registered. + pub fn register_channel(&self, channel: &ChannelId) { match self.senders().entry(channel.clone()) { // This ever happening indicates a serious logic error. - Entry::Occupied(_) => return Err(RegisterError::Duplicate(channel.clone())), + Entry::Occupied(_) => panic!("duplicate channel registration for channel {channel}"), Entry::Vacant(entry) => { entry.insert(Self::make_sender()); } } - - Ok(()) } // panic: if ``channel`` has not been previously registered, and was not @@ -230,9 +221,3 @@ impl Broadcaster { tx } } - -#[derive(Debug, thiserror::Error)] -pub enum RegisterError { - #[error("duplicate broadcast registration for channel {0}")] - Duplicate(ChannelId), -} -- cgit v1.2.3