diff --git a/crates/api_clients/storyteller_client/src/error/api_error.rs b/crates/api_clients/storyteller_client/src/error/api_error.rs index b85d424ea8..ea92b62b21 100644 --- a/crates/api_clients/storyteller_client/src/error/api_error.rs +++ b/crates/api_clients/storyteller_client/src/error/api_error.rs @@ -11,6 +11,9 @@ pub enum ApiError { /// 401. The request was not authorized. Unauthorized(String), + + // 402. Payment required. + PaymentRequired(String), /// 403. The request was forbidden. Forbidden(String), @@ -56,6 +59,7 @@ impl Display for ApiError { match self { // Server response code errors ApiError::InvalidRequest(msg) => write!(f, "Invalid request: {}", msg), + ApiError::PaymentRequired(msg) => write!(f, "Payment required: {}", msg), ApiError::Unauthorized(msg) => write!(f, "Unauthorized: {}", msg), ApiError::Forbidden(msg) => write!(f, "Forbidden: {}", msg), ApiError::NotFound(msg) => write!(f, "Not found: {}", msg), @@ -80,6 +84,13 @@ impl Display for ApiError { impl From for ApiError { fn from(error: reqwest::Error) -> Self { + if let Some(status) = error.status() { + let status = status.as_u16(); + match status { + 402 => return ApiError::PaymentRequired(error.to_string()), + _ => {} // NB: Fallthrough. + } + } if error.is_timeout() { ApiError::Timeout(error.to_string()) } else if error.is_connect() { diff --git a/crates/api_clients/storyteller_client/src/utils/filter_bad_response.rs b/crates/api_clients/storyteller_client/src/utils/filter_bad_response.rs index 13fe4bad23..c971747042 100644 --- a/crates/api_clients/storyteller_client/src/utils/filter_bad_response.rs +++ b/crates/api_clients/storyteller_client/src/utils/filter_bad_response.rs @@ -38,6 +38,7 @@ pub async fn filter_bad_response(response: reqwest::Response) -> Result Err(ApiError::Unauthorized(response_body)), + STATUS_402_PAYMENT_REQUIRED => Err(ApiError::PaymentRequired(response_body)), STATUS_403_FORBIDDEN => Err(ApiError::Forbidden(response_body)), STATUS_404_NOT_FOUND => Err(ApiError::NotFound(response_body)), STATUS_429_TOO_MANY_REQUESTS => Err(ApiError::TooManyRequests(response_body)), diff --git a/crates/api_clients/storyteller_client/src/utils/status_codes.rs b/crates/api_clients/storyteller_client/src/utils/status_codes.rs index c15847e129..e2bf44bffb 100644 --- a/crates/api_clients/storyteller_client/src/utils/status_codes.rs +++ b/crates/api_clients/storyteller_client/src/utils/status_codes.rs @@ -1,5 +1,6 @@ pub const STATUS_401_UNAUTHORIZED : u16 = 401u16; +pub const STATUS_402_PAYMENT_REQUIRED : u16 = 402u16; pub const STATUS_403_FORBIDDEN : u16 = 403u16; pub const STATUS_404_NOT_FOUND : u16 = 404u16; @@ -15,6 +16,7 @@ mod tests { #[test] pub fn test_codes() { assert_eq!(STATUS_401_UNAUTHORIZED, 401); + assert_eq!(STATUS_402_PAYMENT_REQUIRED, 402); assert_eq!(STATUS_403_FORBIDDEN, 403); assert_eq!(STATUS_404_NOT_FOUND, 404); assert_eq!(STATUS_429_TOO_MANY_REQUESTS, 429); diff --git a/crates/service/web/storyteller_web/src/http_server/endpoints/generate/common/payments_error_test.rs b/crates/service/web/storyteller_web/src/http_server/endpoints/generate/common/payments_error_test.rs index b60f336ed3..27a4e78829 100644 --- a/crates/service/web/storyteller_web/src/http_server/endpoints/generate/common/payments_error_test.rs +++ b/crates/service/web/storyteller_web/src/http_server/endpoints/generate/common/payments_error_test.rs @@ -4,7 +4,7 @@ use crate::http_server::common_responses::common_web_error::CommonWebError; pub fn payments_error_test(prompt: &str) -> Result<(), CommonWebError> { let prompt = prompt.trim().to_ascii_lowercase(); - if prompt == "trigger_payments_failure" { + if prompt == "trigger_payment_failure" { return Err(CommonWebError::PaymentRequired); } @@ -22,8 +22,13 @@ pub fn payments_error_test(prompt: &str) -> Result<(), CommonWebError> { } // TODO(bt,2025-08-30): Remove these later. - if prompt.contains("payment") && prompt.contains("error") { - return Err(CommonWebError::PaymentRequired) + if prompt.contains("payment") { + if prompt.contains("error") { + return Err(CommonWebError::PaymentRequired) + } + if prompt.contains("failure") { + return Err(CommonWebError::PaymentRequired) + } } Ok(())