diff --git a/akd/crates/akd_storage/src/ms_sql/tables/akd_storable_for_ms_sql.rs b/akd/crates/akd_storage/src/ms_sql/tables/akd_storable_for_ms_sql.rs index 576a7b9a97..4e65c0200c 100644 --- a/akd/crates/akd_storage/src/ms_sql/tables/akd_storable_for_ms_sql.rs +++ b/akd/crates/akd_storage/src/ms_sql/tables/akd_storable_for_ms_sql.rs @@ -437,9 +437,8 @@ impl AkdStorableForMsSql for DbRecord { } StorageType::TreeNode => { let bin = St::get_full_binary_key_id(key); - // These are constructed from a safe key, they should never fail let key = TreeNodeWithPreviousValue::key_from_full_binary(&bin) - .expect("Failed to decode key"); // TODO: should this be an error? + .map_err(|e| StorageError::Other(format!("Failed to decode TreeNode key: {}", e)))?; params.add("label_len", Box::new(key.0.label_len as i32)); params.add("label_val", Box::new(key.0.label_val.to_vec())); @@ -455,8 +454,8 @@ impl AkdStorableForMsSql for DbRecord { } StorageType::ValueState => { let bin = St::get_full_binary_key_id(key); - // These are constructed from a safe key, they should never fail - let key = ValueState::key_from_full_binary(&bin).expect("Failed to decode key"); // TODO: should this be an error? + let key = ValueState::key_from_full_binary(&bin) + .map_err(|e| StorageError::Other(format!("Failed to decode ValueState key: {}", e)))?; params.add("raw_label", Box::new(key.0.clone())); params.add("epoch", Box::new(key.1 as i64)); @@ -485,9 +484,8 @@ impl AkdStorableForMsSql for DbRecord { let mut rows = Vec::new(); for k in key { let bin = St::get_full_binary_key_id(k); - // These are constructed from a safe key, they should never fail let key = TreeNodeWithPreviousValue::key_from_full_binary(&bin) - .expect("Failed to decode key"); + .map_err(|e| StorageError::Other(format!("Failed to decode TreeNode key: {}", e)))?; let row = (key.0.label_len as i32, key.0.label_val.to_vec()).into_row(); rows.push(row); @@ -498,8 +496,8 @@ impl AkdStorableForMsSql for DbRecord { let mut rows = Vec::new(); for k in key { let bin = St::get_full_binary_key_id(k); - // These are constructed from a safe key, they should never fail - let key = ValueState::key_from_full_binary(&bin).expect("Failed to decode key"); // TODO: should this be an error? + let key = ValueState::key_from_full_binary(&bin) + .map_err(|e| StorageError::Other(format!("Failed to decode ValueState key: {}", e)))?; let row = (key.0.clone(), key.1 as i64).into_row(); rows.push(row); diff --git a/akd/crates/akd_storage/src/ms_sql/tables/vrf_key.rs b/akd/crates/akd_storage/src/ms_sql/tables/vrf_key.rs index 366ca8cd00..87cca731dc 100644 --- a/akd/crates/akd_storage/src/ms_sql/tables/vrf_key.rs +++ b/akd/crates/akd_storage/src/ms_sql/tables/vrf_key.rs @@ -79,9 +79,14 @@ pub fn from_row(row: &ms_database::Row) -> Result for VrfRootKeyType { - fn from(value: i16) -> Self { +#[derive(Debug, Error)] +#[error("Invalid VrfRootKeyType value from database: {0}")] +pub struct InvalidVrfRootKeyTypeError(i16); + +impl TryFrom for VrfRootKeyType { + type Error = InvalidVrfRootKeyTypeError; + + fn try_from(value: i16) -> Result { match value { - 1 => VrfRootKeyType::SymmetricKey, - 2 => VrfRootKeyType::RsaKey, + 1 => Ok(VrfRootKeyType::SymmetricKey), + 2 => Ok(VrfRootKeyType::RsaKey), #[cfg(test)] - 0 => VrfRootKeyType::None, - _ => panic!("Invalid VrfRootKeyType value: {}", value), + 0 => Ok(VrfRootKeyType::None), + _ => { + error!("Invalid VrfRootKeyType value from database: {}", value); + Err(InvalidVrfRootKeyTypeError(value)) + } } } } diff --git a/akd/crates/ms_database/src/pool.rs b/akd/crates/ms_database/src/pool.rs index e8f150f3ce..8daaa0e12a 100644 --- a/akd/crates/ms_database/src/pool.rs +++ b/akd/crates/ms_database/src/pool.rs @@ -101,14 +101,22 @@ impl ManagedConnection { } async fn ping(&mut self) -> Result { - let row = self + let rows = self .0 .simple_query("SELECT 1") .await? .into_first_result() .await?; - debug!(?row, "Ping response"); - let value = row[0].get(0).expect("value is present"); + debug!(?rows, "Ping response"); + + let row = rows.first().ok_or_else(|| { + tiberius::error::Error::Conversion("Ping query returned no rows".into()) + })?; + + let value = row.get(0).ok_or_else(|| { + tiberius::error::Error::Conversion("Ping query returned no columns".into()) + })?; + Ok(value) } } diff --git a/akd/crates/publisher/src/config.rs b/akd/crates/publisher/src/config.rs index f7746f874c..c2ee7f6274 100644 --- a/akd/crates/publisher/src/config.rs +++ b/akd/crates/publisher/src/config.rs @@ -103,11 +103,10 @@ impl ApplicationConfig { } /// Get the web server bind address as a SocketAddr - /// Panics if the address is invalid - pub fn socket_address(&self) -> std::net::SocketAddr { + pub fn socket_address(&self) -> Result { self.web_server_bind_address .parse() - .expect("Invalid web server bind address") + .map_err(|e| ConfigError::Message(format!("Invalid web server bind address '{}': {}", self.web_server_bind_address, e))) } pub fn api_key_valid(&self, api_key: &str) -> bool { diff --git a/akd/crates/publisher/src/lib.rs b/akd/crates/publisher/src/lib.rs index 8363308c28..e606ad55db 100644 --- a/akd/crates/publisher/src/lib.rs +++ b/akd/crates/publisher/src/lib.rs @@ -151,12 +151,13 @@ async fn start_web( .route_layer(from_fn_with_state(app_state.clone(), auth)) .with_state(app_state); - let listener = TcpListener::bind(&config.socket_address()) + let socket_addr = config.socket_address().context("Failed to parse socket address")?; + let listener = TcpListener::bind(&socket_addr) .await .context("Socket bind failed")?; info!( "Publisher web server listening on {}", - config.socket_address() + socket_addr ); axum::serve(listener, app.into_make_service()) .with_graceful_shutdown(async move { diff --git a/akd/crates/reader/src/config.rs b/akd/crates/reader/src/config.rs index e8b4f5d6d3..bf13c640a2 100644 --- a/akd/crates/reader/src/config.rs +++ b/akd/crates/reader/src/config.rs @@ -75,10 +75,9 @@ impl ApplicationConfig { } /// Get the web server bind address as a SocketAddr - /// Panics if the address is invalid - pub fn socket_address(&self) -> std::net::SocketAddr { + pub fn socket_address(&self) -> Result { self.web_server_bind_address .parse() - .expect("Invalid web server bind address") + .map_err(|e| ConfigError::Message(format!("Invalid web server bind address '{}': {}", self.web_server_bind_address, e))) } } diff --git a/akd/crates/reader/src/lib.rs b/akd/crates/reader/src/lib.rs index d414d962d2..5b314f8088 100644 --- a/akd/crates/reader/src/lib.rs +++ b/akd/crates/reader/src/lib.rs @@ -48,11 +48,12 @@ pub async fn start( .merge(crate::routes::api_routes()) .with_state(app_state); - let listener = TcpListener::bind(&config.socket_address()) + let socket_addr = config.socket_address().context("Failed to parse socket address")?; + let listener = TcpListener::bind(&socket_addr) .await .context("Socket bind failed")?; info!( - socket_address = %config.socket_address(), + socket_address = %socket_addr, "Reader web server listening" );