fix(u16_wrappers): Improve error handling and validation for CustomerListLimit conversions

This commit is contained in:
Venu Madhav
2025-10-27 16:40:07 +05:30
parent e8de4270f5
commit babb698b98
3 changed files with 24 additions and 19 deletions

View File

@ -15,13 +15,13 @@ pub const MAX_DISPUTE_POLLING_INTERVAL_IN_HOURS: i32 = 24;
pub const DEFAULT_DISPUTE_POLLING_INTERVAL_IN_HOURS: i32 = 24; pub const DEFAULT_DISPUTE_POLLING_INTERVAL_IN_HOURS: i32 = 24;
/// Customer List Lower Limit /// Customer List Lower Limit
pub const CUSTOMER_LIST_LOWER_LIMIT: u16 = 1; pub const CUSTOMER_LIST_LOWER_LIMIT: i16 = 1;
/// Customer List Upper Limit /// Customer List Upper Limit
pub const CUSTOMER_LIST_UPPER_LIMIT: u16 = 100; pub const CUSTOMER_LIST_UPPER_LIMIT: i16 = 100;
/// Customer List Default Limit /// Customer List Default Limit
pub const CUSTOMER_LIST_DEFAULT_LIMIT: u16 = 20; pub const CUSTOMER_LIST_DEFAULT_LIMIT: i16 = 20;
/// Default payment intent statuses that trigger a webhook /// Default payment intent statuses that trigger a webhook
pub const DEFAULT_PAYMENT_WEBHOOK_TRIGGER_STATUSES: &[common_enums::IntentStatus] = &[ pub const DEFAULT_PAYMENT_WEBHOOK_TRIGGER_STATUSES: &[common_enums::IntentStatus] = &[

View File

@ -463,7 +463,7 @@ mod u16_wrappers {
where where
D: serde::Deserializer<'de>, D: serde::Deserializer<'de>,
{ {
let val = u16::deserialize(deserializer)?; let val = i16::deserialize(deserializer)?;
if val < CUSTOMER_LIST_LOWER_LIMIT { if val < CUSTOMER_LIST_LOWER_LIMIT {
Err(D::Error::custom(format!( Err(D::Error::custom(format!(
"CustomerListLimit cannot be less than {}", "CustomerListLimit cannot be less than {}",
@ -475,7 +475,7 @@ mod u16_wrappers {
CUSTOMER_LIST_UPPER_LIMIT CUSTOMER_LIST_UPPER_LIMIT
))) )))
} else { } else {
Ok(Self(val as i16)) Ok(Self(val))
} }
} }
} }
@ -502,37 +502,40 @@ mod u16_wrappers {
impl Default for CustomerListLimit { impl Default for CustomerListLimit {
/// Default for `CustomerListLimit` is `20` /// Default for `CustomerListLimit` is `20`
fn default() -> Self { fn default() -> Self {
Self(CUSTOMER_LIST_DEFAULT_LIMIT as i16) Self(CUSTOMER_LIST_DEFAULT_LIMIT)
}
}
impl From<u16> for CustomerListLimit {
fn from(value: u16) -> Self {
Self(value.clamp(CUSTOMER_LIST_LOWER_LIMIT, CUSTOMER_LIST_UPPER_LIMIT) as i16)
} }
} }
impl CustomerListLimit { impl CustomerListLimit {
/// Creates a new CustomerListLimit with validation /// Creates a new CustomerListLimit with validation
pub fn new(value: u16) -> Result<Self, String> { pub fn new(value: u16) -> Result<Self, String> {
if value < CUSTOMER_LIST_LOWER_LIMIT { // Convert constants to u16 for comparison - these should always succeed
let lower_u16 = u16::try_from(CUSTOMER_LIST_LOWER_LIMIT)
.map_err(|_| "Invalid lower limit constant".to_string())?;
let upper_u16 = u16::try_from(CUSTOMER_LIST_UPPER_LIMIT)
.map_err(|_| "Invalid upper limit constant".to_string())?;
if value < lower_u16 {
Err(format!( Err(format!(
"CustomerListLimit cannot be less than {}", "CustomerListLimit cannot be less than {}",
CUSTOMER_LIST_LOWER_LIMIT CUSTOMER_LIST_LOWER_LIMIT
)) ))
} else if value > CUSTOMER_LIST_UPPER_LIMIT { } else if value > upper_u16 {
Err(format!( Err(format!(
"CustomerListLimit exceeds the maximum allowed value of {}", "CustomerListLimit exceeds the maximum allowed value of {}",
CUSTOMER_LIST_UPPER_LIMIT CUSTOMER_LIST_UPPER_LIMIT
)) ))
} else { } else {
Ok(Self(value as i16)) let inner = i16::try_from(value)
.map_err(|_| "Value too large for internal representation".to_string())?;
Ok(Self(inner))
} }
} }
/// Returns the inner u16 value /// Returns the limit as u16 for external compatibility
pub fn get_value(&self) -> u16 { pub fn get_value(&self) -> Result<u16, String> {
self.0 as u16 u16::try_from(self.0)
.map_err(|_| "Internal value cannot be converted to u16".to_string())
} }
} }
} }

View File

@ -637,7 +637,9 @@ pub async fn list_customers_with_count(
})?; })?;
let customer_list_constraints = crate::db::customers::CustomerListConstraints { let customer_list_constraints = crate::db::customers::CustomerListConstraints {
limit: request.limit.unwrap_or_else(|| limit.get_value()), limit: request
.limit
.unwrap_or_else(|| limit.get_value().unwrap_or(20)),
offset: request.offset, offset: request.offset,
customer_id: request.customer_id, customer_id: request.customer_id,
time_range: request.time_range, time_range: request.time_range,