refactor(errors): error enums to use 'static str (#472)

This commit is contained in:
Narayan Bhat
2023-01-30 18:57:05 +05:30
committed by GitHub
parent fa7d087c0d
commit 24351a6c85
25 changed files with 84 additions and 79 deletions

View File

@ -20,7 +20,10 @@ pub enum StripeErrorCode {
InvalidRequestUrl, InvalidRequestUrl,
#[error(error_type = StripeErrorType::InvalidRequestError, code = "parameter_missing", message = "Missing required param: {field_name}.")] #[error(error_type = StripeErrorType::InvalidRequestError, code = "parameter_missing", message = "Missing required param: {field_name}.")]
ParameterMissing { field_name: String, param: String }, ParameterMissing {
field_name: &'static str,
param: &'static str,
},
#[error( #[error(
error_type = StripeErrorType::InvalidRequestError, code = "parameter_unknown", error_type = StripeErrorType::InvalidRequestError, code = "parameter_unknown",
@ -327,7 +330,7 @@ impl From<errors::ApiErrorResponse> for StripeErrorCode {
| errors::ApiErrorResponse::InvalidHttpMethod => Self::InvalidRequestUrl, | errors::ApiErrorResponse::InvalidHttpMethod => Self::InvalidRequestUrl,
errors::ApiErrorResponse::MissingRequiredField { field_name } => { errors::ApiErrorResponse::MissingRequiredField { field_name } => {
Self::ParameterMissing { Self::ParameterMissing {
field_name: field_name.to_owned(), field_name,
param: field_name, param: field_name,
} }
} }
@ -395,8 +398,8 @@ impl From<errors::ApiErrorResponse> for StripeErrorCode {
Self::PreconditionFailed { message } Self::PreconditionFailed { message }
} }
errors::ApiErrorResponse::InvalidDataValue { field_name } => Self::ParameterMissing { errors::ApiErrorResponse::InvalidDataValue { field_name } => Self::ParameterMissing {
field_name: field_name.to_owned(), field_name,
param: field_name.to_owned(), param: field_name,
}, },
errors::ApiErrorResponse::MaximumRefundCount => Self::MaximumRefundCount, errors::ApiErrorResponse::MaximumRefundCount => Self::MaximumRefundCount,
errors::ApiErrorResponse::PaymentNotSucceeded => Self::PaymentFailed, errors::ApiErrorResponse::PaymentNotSucceeded => Self::PaymentFailed,

View File

@ -383,7 +383,7 @@ impl TryFrom<&types::PaymentsAuthorizeRouterData> for AdyenPaymentRequest {
} }
}, },
_ => Err(errors::ConnectorError::MissingRequiredField { _ => Err(errors::ConnectorError::MissingRequiredField {
field_name: "payment_method".to_string(), field_name: "payment_method",
}), }),
}?; }?;
@ -411,7 +411,7 @@ impl TryFrom<&types::PaymentsAuthorizeRouterData> for AdyenPaymentRequest {
reference, reference,
return_url: item.router_return_url.clone().ok_or( return_url: item.router_return_url.clone().ok_or(
errors::ConnectorError::MissingRequiredField { errors::ConnectorError::MissingRequiredField {
field_name: "router_return_url".into(), field_name: "router_return_url",
}, },
)?, )?,
shopper_interaction, shopper_interaction,

View File

@ -316,7 +316,7 @@ impl<F, T>
}) })
.transpose() .transpose()
.change_context(errors::ConnectorError::MissingRequiredField { .change_context(errors::ConnectorError::MissingRequiredField {
field_name: "connector_metadata".to_string(), field_name: "connector_metadata",
})?; })?;
Ok(Self { Ok(Self {
@ -372,7 +372,7 @@ impl<F> TryFrom<&types::RefundsRouterData<F>> for CreateRefundRequest {
.as_ref() .as_ref()
.get_required_value("connector_metadata") .get_required_value("connector_metadata")
.change_context(errors::ConnectorError::MissingRequiredField { .change_context(errors::ConnectorError::MissingRequiredField {
field_name: "connector_metadata".to_string(), field_name: "connector_metadata",
})? })?
.clone(); .clone();
@ -384,7 +384,7 @@ impl<F> TryFrom<&types::RefundsRouterData<F>> for CreateRefundRequest {
payment: payment_details payment: payment_details
.parse_value("PaymentDetails") .parse_value("PaymentDetails")
.change_context(errors::ConnectorError::MissingRequiredField { .change_context(errors::ConnectorError::MissingRequiredField {
field_name: "payment_details".to_string(), field_name: "payment_details",
})?, })?,
currency_code: item.request.currency.to_string(), currency_code: item.request.currency.to_string(),
reference_transaction_id: item.request.connector_transaction_id.clone(), reference_transaction_id: item.request.connector_transaction_id.clone(),

View File

@ -55,7 +55,7 @@ impl TryFrom<&types::PaymentsSessionRouterData> for KlarnaSessionRequest {
}], }],
}), }),
None => Err(report!(errors::ConnectorError::MissingRequiredField { None => Err(report!(errors::ConnectorError::MissingRequiredField {
field_name: "product_name".to_string() field_name: "product_name",
})), })),
} }
} }
@ -98,7 +98,7 @@ impl TryFrom<&types::PaymentsAuthorizeRouterData> for KlarnaPaymentsRequest {
}], }],
}), }),
None => Err(report!(errors::ConnectorError::MissingRequiredField { None => Err(report!(errors::ConnectorError::MissingRequiredField {
field_name: "product_name".to_string() field_name: "product_name"
})), })),
} }
} }

View File

@ -119,13 +119,13 @@ impl TryFrom<&types::PaymentsAuthorizeRouterData> for PayuPaymentsRequest {
}?; }?;
let browser_info = item.request.browser_info.clone().ok_or( let browser_info = item.request.browser_info.clone().ok_or(
errors::ConnectorError::MissingRequiredField { errors::ConnectorError::MissingRequiredField {
field_name: "browser_info".to_string(), field_name: "browser_info",
}, },
)?; )?;
Ok(Self { Ok(Self {
customer_ip: browser_info.ip_address.ok_or( customer_ip: browser_info.ip_address.ok_or(
errors::ConnectorError::MissingRequiredField { errors::ConnectorError::MissingRequiredField {
field_name: "browser_info.ip_address".to_string(), field_name: "browser_info.ip_address",
}, },
)?, )?,
merchant_pos_id: auth_type.merchant_pos_id, merchant_pos_id: auth_type.merchant_pos_id,
@ -133,7 +133,7 @@ impl TryFrom<&types::PaymentsAuthorizeRouterData> for PayuPaymentsRequest {
currency_code: item.request.currency, currency_code: item.request.currency,
description: item.description.clone().ok_or( description: item.description.clone().ok_or(
errors::ConnectorError::MissingRequiredField { errors::ConnectorError::MissingRequiredField {
field_name: "item.description".to_string(), field_name: "item.description",
}, },
)?, )?,
pay_methods: payment_method, pay_methods: payment_method,
@ -501,7 +501,7 @@ impl<F> TryFrom<&types::RefundsRouterData<F>> for PayuRefundRequest {
refund: PayuRefundRequestData { refund: PayuRefundRequestData {
description: item.request.reason.clone().ok_or( description: item.request.reason.clone().ok_or(
errors::ConnectorError::MissingRequiredField { errors::ConnectorError::MissingRequiredField {
field_name: "item.request.reason".to_string(), field_name: "item.request.reason",
}, },
)?, )?,
amount: None, amount: None,

View File

@ -167,25 +167,25 @@ fn validate_shipping_address_against_payment_method(
{ {
fp_utils::when(shipping_address.name.is_none(), || { fp_utils::when(shipping_address.name.is_none(), || {
Err(errors::ConnectorError::MissingRequiredField { Err(errors::ConnectorError::MissingRequiredField {
field_name: "shipping.first_name".to_string(), field_name: "shipping.first_name",
}) })
})?; })?;
fp_utils::when(shipping_address.line1.is_none(), || { fp_utils::when(shipping_address.line1.is_none(), || {
Err(errors::ConnectorError::MissingRequiredField { Err(errors::ConnectorError::MissingRequiredField {
field_name: "shipping.line1".to_string(), field_name: "shipping.line1",
}) })
})?; })?;
fp_utils::when(shipping_address.country.is_none(), || { fp_utils::when(shipping_address.country.is_none(), || {
Err(errors::ConnectorError::MissingRequiredField { Err(errors::ConnectorError::MissingRequiredField {
field_name: "shipping.country".to_string(), field_name: "shipping.country",
}) })
})?; })?;
fp_utils::when(shipping_address.zip.is_none(), || { fp_utils::when(shipping_address.zip.is_none(), || {
Err(errors::ConnectorError::MissingRequiredField { Err(errors::ConnectorError::MissingRequiredField {
field_name: "shipping.zip".to_string(), field_name: "shipping.zip",
}) })
})?; })?;
} }

View File

@ -7,11 +7,11 @@ use crate::{
}; };
pub fn missing_field_err( pub fn missing_field_err(
message: &str, message: &'static str,
) -> Box<dyn Fn() -> error_stack::Report<errors::ConnectorError> + '_> { ) -> Box<dyn Fn() -> error_stack::Report<errors::ConnectorError> + '_> {
Box::new(|| { Box::new(move || {
errors::ConnectorError::MissingRequiredField { errors::ConnectorError::MissingRequiredField {
field_name: message.to_string(), field_name: message,
} }
.into() .into()
}) })

View File

@ -211,7 +211,7 @@ fn build_customer_info(
) -> Result<Customer, error_stack::Report<errors::ConnectorError>> { ) -> Result<Customer, error_stack::Report<errors::ConnectorError>> {
let (billing, address) = let (billing, address) =
get_address(payment_address).ok_or(errors::ConnectorError::MissingRequiredField { get_address(payment_address).ok_or(errors::ConnectorError::MissingRequiredField {
field_name: "billing.address.country".into(), field_name: "billing.address.country",
})?; })?;
let number_with_country_code = billing.phone.as_ref().and_then(|phone| { let number_with_country_code = billing.phone.as_ref().and_then(|phone| {

View File

@ -87,7 +87,7 @@ where
.map(transform_fn); .map(transform_fn);
reference_id.ok_or_else(|| { reference_id.ok_or_else(|| {
errors::ConnectorError::MissingRequiredField { errors::ConnectorError::MissingRequiredField {
field_name: "links.events".to_string(), field_name: "links.events",
} }
.into() .into()
}) })

View File

@ -93,7 +93,7 @@ impl TryFrom<&types::PaymentsAuthorizeRouterData> for WorldpayPaymentsRequest {
}, },
transaction_reference: item.attempt_id.clone().ok_or( transaction_reference: item.attempt_id.clone().ok_or(
errors::ConnectorError::MissingRequiredField { errors::ConnectorError::MissingRequiredField {
field_name: "attempt_id".to_string(), field_name: "attempt_id",
}, },
)?, )?,
channel: None, channel: None,
@ -160,7 +160,7 @@ impl TryFrom<types::PaymentsResponseRouterData<WorldpayPaymentsResponse>>
status: match item.response.outcome { status: match item.response.outcome {
Some(outcome) => enums::AttemptStatus::from(outcome), Some(outcome) => enums::AttemptStatus::from(outcome),
None => Err(errors::ConnectorError::MissingRequiredField { None => Err(errors::ConnectorError::MissingRequiredField {
field_name: "outcome".to_string(), field_name: "outcome",
})?, })?,
}, },
description: item.response.description, description: item.response.description,

View File

@ -54,8 +54,11 @@ pub enum StorageError {
DatabaseError(error_stack::Report<storage_errors::DatabaseError>), DatabaseError(error_stack::Report<storage_errors::DatabaseError>),
#[error("ValueNotFound: {0}")] #[error("ValueNotFound: {0}")]
ValueNotFound(String), ValueNotFound(String),
#[error("DuplicateValue: {0}")] #[error("DuplicateValue: {entity} already exists {key:?}")]
DuplicateValue(String), DuplicateValue {
entity: &'static str,
key: Option<String>,
},
#[error("KV error")] #[error("KV error")]
KVError, KVError,
#[error("Serialization failure")] #[error("Serialization failure")]
@ -224,7 +227,7 @@ pub enum ConnectorError {
#[error("Failed to handle connector response")] #[error("Failed to handle connector response")]
ResponseHandlingFailed, ResponseHandlingFailed,
#[error("Missing required field: {field_name}")] #[error("Missing required field: {field_name}")]
MissingRequiredField { field_name: String }, MissingRequiredField { field_name: &'static str },
#[error("Failed to obtain authentication type")] #[error("Failed to obtain authentication type")]
FailedToObtainAuthType, FailedToObtainAuthType,
#[error("Failed to obtain certificate")] #[error("Failed to obtain certificate")]
@ -274,7 +277,7 @@ pub enum VaultError {
#[error("The given payment method is currently not supported in vault")] #[error("The given payment method is currently not supported in vault")]
PaymentMethodNotSupported, PaymentMethodNotSupported,
#[error("Missing required field: {field_name}")] #[error("Missing required field: {field_name}")]
MissingRequiredField { field_name: String }, MissingRequiredField { field_name: &'static str },
#[error("The card vault returned an unexpected response: {0:?}")] #[error("The card vault returned an unexpected response: {0:?}")]
UnexpectedResponseError(bytes::Bytes), UnexpectedResponseError(bytes::Bytes),
} }
@ -306,9 +309,9 @@ pub enum ProcessTrackerError {
#[error("Failed to fetch processes from database")] #[error("Failed to fetch processes from database")]
ProcessFetchingFailed, ProcessFetchingFailed,
#[error("Failed while fetching: {resource_name}")] #[error("Failed while fetching: {resource_name}")]
ResourceFetchingFailed { resource_name: String }, ResourceFetchingFailed { resource_name: &'static str },
#[error("Failed while executing: {flow}")] #[error("Failed while executing: {flow}")]
FlowExecutionError { flow: String }, FlowExecutionError { flow: &'static str },
#[error("Not Implemented")] #[error("Not Implemented")]
NotImplemented, NotImplemented,
#[error("Job not found")] #[error("Job not found")]

View File

@ -28,7 +28,7 @@ pub enum ApiErrorResponse {
#[error(error_type = ErrorType::InvalidRequestError, code = "IR_04", message = "The HTTP method is not applicable for this API.")] #[error(error_type = ErrorType::InvalidRequestError, code = "IR_04", message = "The HTTP method is not applicable for this API.")]
InvalidHttpMethod, InvalidHttpMethod,
#[error(error_type = ErrorType::InvalidRequestError, code = "IR_05", message = "Missing required param: {field_name}.")] #[error(error_type = ErrorType::InvalidRequestError, code = "IR_05", message = "Missing required param: {field_name}.")]
MissingRequiredField { field_name: String }, MissingRequiredField { field_name: &'static str },
#[error( #[error(
error_type = ErrorType::InvalidRequestError, code = "IR_06", error_type = ErrorType::InvalidRequestError, code = "IR_06",
message = "{field_name} contains invalid data. Expected format is {expected_format}." message = "{field_name} contains invalid data. Expected format is {expected_format}."

View File

@ -86,9 +86,7 @@ impl ConnectorErrorExt for error_stack::Report<errors::ConnectorError> {
errors::ApiErrorResponse::PaymentAuthorizationFailed { data } errors::ApiErrorResponse::PaymentAuthorizationFailed { data }
} }
errors::ConnectorError::MissingRequiredField { field_name } => { errors::ConnectorError::MissingRequiredField { field_name } => {
errors::ApiErrorResponse::MissingRequiredField { errors::ApiErrorResponse::MissingRequiredField { field_name }
field_name: field_name.clone(),
}
} }
errors::ConnectorError::NotImplemented(reason) => { errors::ConnectorError::NotImplemented(reason) => {
errors::ApiErrorResponse::NotImplemented { errors::ApiErrorResponse::NotImplemented {

View File

@ -257,7 +257,7 @@ where
let resource_id = api::PaymentIdTypeExt::get_payment_intent_id(&req.resource_id) let resource_id = api::PaymentIdTypeExt::get_payment_intent_id(&req.resource_id)
.change_context(errors::ApiErrorResponse::MissingRequiredField { .change_context(errors::ApiErrorResponse::MissingRequiredField {
field_name: "payment_id".to_string(), field_name: "payment_id",
})?; })?;
let connector_data = api::ConnectorData::get_connector_by_name( let connector_data = api::ConnectorData::get_connector_by_name(

View File

@ -539,7 +539,7 @@ pub(crate) async fn call_payment_method(
} }
} }
None => Err(report!(errors::ApiErrorResponse::MissingRequiredField { None => Err(report!(errors::ApiErrorResponse::MissingRequiredField {
field_name: "customer".to_string() field_name: "customer"
}) })
.attach_printable("Missing Customer Object")), .attach_printable("Missing Customer Object")),
} }
@ -568,12 +568,12 @@ pub(crate) async fn call_payment_method(
} }
}, },
None => Err(report!(errors::ApiErrorResponse::MissingRequiredField { None => Err(report!(errors::ApiErrorResponse::MissingRequiredField {
field_name: "payment_method_type".to_string() field_name: "payment_method_type"
}) })
.attach_printable("PaymentMethodType Required")), .attach_printable("PaymentMethodType Required")),
}, },
None => Err(report!(errors::ApiErrorResponse::MissingRequiredField { None => Err(report!(errors::ApiErrorResponse::MissingRequiredField {
field_name: "payment_method_data".to_string() field_name: "payment_method_data"
}) })
.attach_printable("PaymentMethodData required Or Card is already saved")), .attach_printable("PaymentMethodData required Or Card is already saved")),
} }
@ -829,7 +829,7 @@ pub(crate) fn validate_payment_method_fields_present(
req.payment_method.is_none() && req.payment_method_data.is_some(), req.payment_method.is_none() && req.payment_method_data.is_some(),
|| { || {
Err(errors::ApiErrorResponse::MissingRequiredField { Err(errors::ApiErrorResponse::MissingRequiredField {
field_name: "payent_method".to_string(), field_name: "payent_method",
}) })
}, },
)?; )?;
@ -840,7 +840,7 @@ pub(crate) fn validate_payment_method_fields_present(
&& req.payment_token.is_none(), && req.payment_token.is_none(),
|| { || {
Err(errors::ApiErrorResponse::MissingRequiredField { Err(errors::ApiErrorResponse::MissingRequiredField {
field_name: "payment_method_data".to_string(), field_name: "payment_method_data",
}) })
}, },
)?; )?;

View File

@ -477,7 +477,7 @@ impl<F: Clone> TryFrom<PaymentData<F>> for types::PaymentsCancelData {
.payment_attempt .payment_attempt
.connector_transaction_id .connector_transaction_id
.ok_or(errors::ApiErrorResponse::MissingRequiredField { .ok_or(errors::ApiErrorResponse::MissingRequiredField {
field_name: "connector_transaction_id".to_string(), field_name: "connector_transaction_id",
})?, })?,
cancellation_reason: payment_data.payment_attempt.cancellation_reason, cancellation_reason: payment_data.payment_attempt.cancellation_reason,
}) })

View File

@ -108,7 +108,7 @@ pub async fn trigger_refund_to_gateway(
let currency = payment_attempt.currency.ok_or_else(|| { let currency = payment_attempt.currency.ok_or_else(|| {
report!(errors::ApiErrorResponse::MissingRequiredField { report!(errors::ApiErrorResponse::MissingRequiredField {
field_name: "currency".to_string() field_name: "currency"
}) })
.attach_printable("Transaction in invalid") .attach_printable("Transaction in invalid")
})?; })?;

View File

@ -64,9 +64,10 @@ mod storage {
.await .await
{ {
Ok(v) if v.contains(&HsetnxReply::KeyNotSet) => { Ok(v) if v.contains(&HsetnxReply::KeyNotSet) => {
Err(errors::StorageError::DuplicateValue( Err(errors::StorageError::DuplicateValue {
"Ephemeral key already exists".to_string(), entity: "ephimeral key",
) key: None,
}
.into()) .into())
} }
Ok(_) => { Ok(_) => {

View File

@ -391,9 +391,10 @@ mod storage {
.serialize_and_set_hash_field_if_not_exist(&key, &field, &created_attempt) .serialize_and_set_hash_field_if_not_exist(&key, &field, &created_attempt)
.await .await
{ {
Ok(HsetnxReply::KeyNotSet) => Err(errors::StorageError::DuplicateValue( Ok(HsetnxReply::KeyNotSet) => Err(errors::StorageError::DuplicateValue {
format!("Payment Attempt already exists for payment_id: {key}"), entity: "payment attempt",
)) key: Some(key),
})
.into_report(), .into_report(),
Ok(HsetnxReply::KeySet) => { Ok(HsetnxReply::KeySet) => {
let conn = pg_connection(&self.master_pool).await; let conn = pg_connection(&self.master_pool).await;

View File

@ -102,9 +102,10 @@ mod storage {
.serialize_and_set_hash_field_if_not_exist(&key, "pi", &created_intent) .serialize_and_set_hash_field_if_not_exist(&key, "pi", &created_intent)
.await .await
{ {
Ok(HsetnxReply::KeyNotSet) => Err(errors::StorageError::DuplicateValue( Ok(HsetnxReply::KeyNotSet) => Err(errors::StorageError::DuplicateValue {
format!("Payment Intent already exists for payment_id: {key}"), entity: "payment_intent",
)) key: Some(key),
})
.into_report(), .into_report(),
Ok(HsetnxReply::KeySet) => { Ok(HsetnxReply::KeySet) => {
let redis_entry = kv::TypedSql { let redis_entry = kv::TypedSql {

View File

@ -128,7 +128,7 @@ impl QueueInterface for MockDb {
) -> CustomResult<Vec<storage::ProcessTracker>, ProcessTrackerError> { ) -> CustomResult<Vec<storage::ProcessTracker>, ProcessTrackerError> {
// [#172]: Implement function for `MockDb` // [#172]: Implement function for `MockDb`
Err(ProcessTrackerError::ResourceFetchingFailed { Err(ProcessTrackerError::ResourceFetchingFailed {
resource_name: "consumer_tasks".to_string(), resource_name: "consumer_tasks",
})? })?
} }

View File

@ -305,13 +305,11 @@ mod storage {
.serialize_and_set_hash_field_if_not_exist(&key, &field, &created_refund) .serialize_and_set_hash_field_if_not_exist(&key, &field, &created_refund)
.await .await
{ {
Ok(HsetnxReply::KeyNotSet) => { Ok(HsetnxReply::KeyNotSet) => Err(errors::StorageError::DuplicateValue {
Err(errors::StorageError::DuplicateValue(format!( entity: "refund",
"Refund already exists refund_id: {}", key: Some(created_refund.refund_id),
&created_refund.refund_id })
))) .into_report(),
.into_report()
}
Ok(HsetnxReply::KeySet) => { Ok(HsetnxReply::KeySet) => {
let conn = pg_connection(&self.master_pool).await; let conn = pg_connection(&self.master_pool).await;

View File

@ -204,7 +204,7 @@ pub fn check_client_secret_and_get_auth(
.get_client_secret() .get_client_secret()
.check_value_present("client_secret") .check_value_present("client_secret")
.map_err(|_| errors::ApiErrorResponse::MissingRequiredField { .map_err(|_| errors::ApiErrorResponse::MissingRequiredField {
field_name: "client_secret".to_owned(), field_name: "client_secret",
})?; })?;
return Ok((Box::new(PublishableKeyAuth), api::AuthFlow::Client)); return Ok((Box::new(PublishableKeyAuth), api::AuthFlow::Client));
} }

View File

@ -7,18 +7,18 @@ use crate::{
}; };
pub trait OptionExt<T> { pub trait OptionExt<T> {
fn check_value_present(&self, field_name: &str) -> RouterResult<()>; fn check_value_present(&self, field_name: &'static str) -> RouterResult<()>;
fn get_required_value(self, field_name: &str) -> RouterResult<T>; fn get_required_value(self, field_name: &'static str) -> RouterResult<T>;
fn parse_enum<E>(self, enum_name: &str) -> CustomResult<E, errors::ParsingError> fn parse_enum<E>(self, enum_name: &'static str) -> CustomResult<E, errors::ParsingError>
where where
T: AsRef<str>, T: AsRef<str>,
E: std::str::FromStr, E: std::str::FromStr,
// Requirement for converting the `Err` variant of `FromStr` to `Report<Err>` // Requirement for converting the `Err` variant of `FromStr` to `Report<Err>`
<E as std::str::FromStr>::Err: std::error::Error + Send + Sync + 'static; <E as std::str::FromStr>::Err: std::error::Error + Send + Sync + 'static;
fn parse_value<U>(self, type_name: &str) -> CustomResult<U, errors::ParsingError> fn parse_value<U>(self, type_name: &'static str) -> CustomResult<U, errors::ParsingError>
where where
T: ValueExt<U>, T: ValueExt<U>,
U: serde::de::DeserializeOwned; U: serde::de::DeserializeOwned;
@ -30,26 +30,26 @@ impl<T> OptionExt<T> for Option<T>
where where
T: std::fmt::Debug, T: std::fmt::Debug,
{ {
fn check_value_present(&self, field_name: &str) -> RouterResult<()> { fn check_value_present(&self, field_name: &'static str) -> RouterResult<()> {
when(self.is_none(), || { when(self.is_none(), || {
Err(Report::new(ApiErrorResponse::MissingRequiredField { Err(
field_name: field_name.to_string(), Report::new(ApiErrorResponse::MissingRequiredField { field_name })
}) .attach_printable(format!("Missing required field {field_name} in {self:?}")),
.attach_printable(format!("Missing required field {field_name} in {self:?}"))) )
}) })
} }
fn get_required_value(self, field_name: &str) -> RouterResult<T> { fn get_required_value(self, field_name: &'static str) -> RouterResult<T> {
match self { match self {
Some(v) => Ok(v), Some(v) => Ok(v),
None => Err(Report::new(ApiErrorResponse::MissingRequiredField { None => Err(
field_name: field_name.to_string(), Report::new(ApiErrorResponse::MissingRequiredField { field_name })
}) .attach_printable(format!("Missing required field {field_name} in {self:?}")),
.attach_printable(format!("Missing required field {field_name} in {self:?}"))), ),
} }
} }
fn parse_enum<E>(self, enum_name: &str) -> CustomResult<E, errors::ParsingError> fn parse_enum<E>(self, enum_name: &'static str) -> CustomResult<E, errors::ParsingError>
where where
T: AsRef<str>, T: AsRef<str>,
E: std::str::FromStr, E: std::str::FromStr,
@ -65,7 +65,7 @@ where
.attach_printable_lazy(|| format!("Invalid {{ {enum_name}: {value:?} }} ")) .attach_printable_lazy(|| format!("Invalid {{ {enum_name}: {value:?} }} "))
} }
fn parse_value<U>(self, type_name: &str) -> CustomResult<U, errors::ParsingError> fn parse_value<U>(self, type_name: &'static str) -> CustomResult<U, errors::ParsingError>
where where
T: ValueExt<U>, T: ValueExt<U>,
U: serde::de::DeserializeOwned, U: serde::de::DeserializeOwned,

View File

@ -157,7 +157,7 @@ async fn should_throw_missing_required_field_for_country() {
assert_eq!( assert_eq!(
*response.unwrap_err().current_context(), *response.unwrap_err().current_context(),
errors::ConnectorError::MissingRequiredField { errors::ConnectorError::MissingRequiredField {
field_name: String::from("billing.address.country") field_name: "billing.address.country"
} }
) )
} }