diff --git a/crates/quicproquo-client/src/lib.rs b/crates/quicproquo-client/src/lib.rs index 95cf779..97b2024 100644 --- a/crates/quicproquo-client/src/lib.rs +++ b/crates/quicproquo-client/src/lib.rs @@ -67,18 +67,33 @@ impl ClientContext { } /// Set (or replace) the auth credentials. + /// + /// # Panics + /// Panics if the RwLock is poisoned (a thread panicked while holding it). + /// A poisoned lock indicates unrecoverable state corruption. + #[allow(clippy::expect_used)] pub fn set_auth(&self, ctx: ClientAuth) { let mut guard = self.auth.write().expect("ClientContext auth lock poisoned"); *guard = Some(ctx); } /// Read the current auth snapshot (cloned). + /// + /// # Panics + /// Panics if the RwLock is poisoned (a thread panicked while holding it). + /// A poisoned lock indicates unrecoverable state corruption. + #[allow(clippy::expect_used)] pub fn get_auth(&self) -> Option { let guard = self.auth.read().expect("ClientContext auth lock poisoned"); guard.clone() } /// Returns true if auth credentials have been set. + /// + /// # Panics + /// Panics if the RwLock is poisoned (a thread panicked while holding it). + /// A poisoned lock indicates unrecoverable state corruption. + #[allow(clippy::expect_used)] pub fn is_authenticated(&self) -> bool { let guard = self.auth.read().expect("ClientContext auth lock poisoned"); guard.is_some() @@ -151,6 +166,11 @@ impl ClientAuth { } /// Set (or replace) the global auth context. +/// +/// # Panics +/// Panics if the RwLock is poisoned (a thread panicked while holding it). +/// A poisoned lock indicates unrecoverable state corruption. +#[allow(clippy::expect_used)] pub fn init_auth(ctx: ClientAuth) { let mut guard = AUTH_CONTEXT.write().expect("AUTH_CONTEXT poisoned"); *guard = Some(ctx); diff --git a/crates/quicproquo-client/src/v2_main.rs b/crates/quicproquo-client/src/v2_main.rs index 2ed86a0..e821529 100644 --- a/crates/quicproquo-client/src/v2_main.rs +++ b/crates/quicproquo-client/src/v2_main.rs @@ -336,7 +336,10 @@ pub fn main() { let rt = tokio::runtime::Builder::new_multi_thread() .enable_all() .build() - .expect("failed to create tokio runtime"); + .unwrap_or_else(|e| { + eprintln!("fatal: {e}"); + std::process::exit(1); + }); if let Err(e) = rt.block_on(run(args)) { eprintln!("error: {e:#}"); diff --git a/crates/quicproquo-rpc/src/client.rs b/crates/quicproquo-rpc/src/client.rs index 56523f7..5ad26fe 100644 --- a/crates/quicproquo-rpc/src/client.rs +++ b/crates/quicproquo-rpc/src/client.rs @@ -40,7 +40,11 @@ impl RpcClient { let quic_tls = quinn::crypto::rustls::QuicClientConfig::try_from(tls) .map_err(|e| RpcError::Connection(format!("TLS config: {e}")))?; - let mut endpoint = Endpoint::client("0.0.0.0:0".parse().expect("valid addr")) + let bind_addr = std::net::SocketAddr::new( + std::net::IpAddr::V4(std::net::Ipv4Addr::UNSPECIFIED), + 0, + ); + let mut endpoint = Endpoint::client(bind_addr) .map_err(|e| RpcError::Connection(e.to_string()))?; endpoint.set_default_client_config(quinn::ClientConfig::new(Arc::new(quic_tls))); diff --git a/crates/quicproquo-sdk/src/config.rs b/crates/quicproquo-sdk/src/config.rs index 7feb20e..277cdd7 100644 --- a/crates/quicproquo-sdk/src/config.rs +++ b/crates/quicproquo-sdk/src/config.rs @@ -32,7 +32,10 @@ pub struct ClientConfig { impl Default for ClientConfig { fn default() -> Self { Self { - server_addr: "127.0.0.1:7000".parse().expect("valid addr"), + server_addr: std::net::SocketAddr::new( + std::net::IpAddr::V4(std::net::Ipv4Addr::new(127, 0, 0, 1)), + 7000, + ), server_name: "localhost".to_string(), db_path: PathBuf::from("conversations.db"), db_password: None, diff --git a/crates/quicproquo-server/src/main.rs b/crates/quicproquo-server/src/main.rs index cf5d360..a0e68a0 100644 --- a/crates/quicproquo-server/src/main.rs +++ b/crates/quicproquo-server/src/main.rs @@ -203,7 +203,7 @@ async fn main() -> anyhow::Result<()> { transport.max_idle_timeout(Some( std::time::Duration::from_secs(300) .try_into() - .expect("300s is a valid IdleTimeout"), + .map_err(|e| anyhow::anyhow!("idle timeout: {e}"))?, )); transport.max_concurrent_bidi_streams(1u32.into()); transport.max_concurrent_uni_streams(0u32.into()); @@ -390,7 +390,7 @@ async fn main() -> anyhow::Result<()> { transport.max_idle_timeout(Some( std::time::Duration::from_secs(120) .try_into() - .expect("120s is valid"), + .map_err(|e| anyhow::anyhow!("idle timeout: {e}"))?, )); qc.transport_config(Arc::new(transport)); Some(qc)