mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-11-02 04:04:43 +08:00
fix(connector): implement ConnectorErrorExt for error_stack::Result<T, ConnectorError> (#1382)
Co-authored-by: Narayan Bhat <48803246+Narayanbhat166@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
a7ac4af5d9
commit
3ef1d2935e
@ -129,7 +129,7 @@ pub async fn accept_dispute(
|
||||
payments::CallConnectorAction::Trigger,
|
||||
)
|
||||
.await
|
||||
.map_err(|error| error.to_dispute_failed_response())
|
||||
.to_dispute_failed_response()
|
||||
.attach_printable("Failed while calling accept dispute connector api")?;
|
||||
let accept_dispute_response =
|
||||
response
|
||||
@ -236,7 +236,7 @@ pub async fn submit_evidence(
|
||||
payments::CallConnectorAction::Trigger,
|
||||
)
|
||||
.await
|
||||
.map_err(|error| error.to_payment_failed_response())
|
||||
.to_dispute_failed_response()
|
||||
.attach_printable("Failed while calling submit evidence connector api")?;
|
||||
let submit_evidence_response =
|
||||
response
|
||||
@ -272,7 +272,7 @@ pub async fn submit_evidence(
|
||||
payments::CallConnectorAction::Trigger,
|
||||
)
|
||||
.await
|
||||
.map_err(|error| error.to_payment_failed_response())
|
||||
.to_dispute_failed_response()
|
||||
.attach_printable("Failed while calling defend dispute connector api")?;
|
||||
let defend_dispute_response = defend_response.response.map_err(|err| {
|
||||
errors::ApiErrorResponse::ExternalConnectorError {
|
||||
|
||||
@ -43,143 +43,153 @@ impl<T> StorageErrorExt<T, errors::ApiErrorResponse>
|
||||
}
|
||||
}
|
||||
|
||||
pub trait ConnectorErrorExt {
|
||||
pub trait ConnectorErrorExt<T> {
|
||||
#[track_caller]
|
||||
fn to_refund_failed_response(self) -> error_stack::Report<errors::ApiErrorResponse>;
|
||||
fn to_refund_failed_response(self) -> error_stack::Result<T, errors::ApiErrorResponse>;
|
||||
#[track_caller]
|
||||
fn to_payment_failed_response(self) -> error_stack::Report<errors::ApiErrorResponse>;
|
||||
fn to_payment_failed_response(self) -> error_stack::Result<T, errors::ApiErrorResponse>;
|
||||
#[track_caller]
|
||||
fn to_verify_failed_response(self) -> error_stack::Report<errors::ApiErrorResponse>;
|
||||
fn to_verify_failed_response(self) -> error_stack::Result<T, errors::ApiErrorResponse>;
|
||||
#[track_caller]
|
||||
fn to_dispute_failed_response(self) -> error_stack::Report<errors::ApiErrorResponse>;
|
||||
fn to_dispute_failed_response(self) -> error_stack::Result<T, errors::ApiErrorResponse>;
|
||||
}
|
||||
|
||||
impl ConnectorErrorExt for error_stack::Report<errors::ConnectorError> {
|
||||
fn to_refund_failed_response(self) -> error_stack::Report<errors::ApiErrorResponse> {
|
||||
let data = match self.current_context() {
|
||||
errors::ConnectorError::ProcessingStepFailed(Some(bytes)) => {
|
||||
let response_str = std::str::from_utf8(bytes);
|
||||
match response_str {
|
||||
Ok(s) => serde_json::from_str(s)
|
||||
.map_err(
|
||||
|error| logger::error!(%error,"Failed to convert response to JSON"),
|
||||
)
|
||||
.ok(),
|
||||
Err(error) => {
|
||||
logger::error!(%error,"Failed to convert response to UTF8 string");
|
||||
None
|
||||
impl<T> ConnectorErrorExt<T> for error_stack::Result<T, errors::ConnectorError> {
|
||||
fn to_refund_failed_response(self) -> error_stack::Result<T, errors::ApiErrorResponse> {
|
||||
self.map_err(|err| {
|
||||
let data = match err.current_context() {
|
||||
errors::ConnectorError::ProcessingStepFailed(Some(bytes)) => {
|
||||
let response_str = std::str::from_utf8(bytes);
|
||||
match response_str {
|
||||
Ok(s) => serde_json::from_str(s)
|
||||
.map_err(
|
||||
|error| logger::error!(%error,"Failed to convert response to JSON"),
|
||||
)
|
||||
.ok(),
|
||||
Err(error) => {
|
||||
logger::error!(%error,"Failed to convert response to UTF8 string");
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => None,
|
||||
};
|
||||
self.change_context(errors::ApiErrorResponse::RefundFailed { data })
|
||||
_ => None,
|
||||
};
|
||||
err.change_context(errors::ApiErrorResponse::RefundFailed { data })
|
||||
})
|
||||
}
|
||||
|
||||
fn to_payment_failed_response(self) -> error_stack::Report<errors::ApiErrorResponse> {
|
||||
let error = match self.current_context() {
|
||||
errors::ConnectorError::ProcessingStepFailed(Some(bytes)) => {
|
||||
let response_str = std::str::from_utf8(bytes);
|
||||
let data = match response_str {
|
||||
Ok(s) => serde_json::from_str(s)
|
||||
.map_err(
|
||||
|error| logger::error!(%error,"Failed to convert response to JSON"),
|
||||
)
|
||||
.ok(),
|
||||
Err(error) => {
|
||||
logger::error!(%error,"Failed to convert response to UTF8 string");
|
||||
None
|
||||
fn to_payment_failed_response(self) -> error_stack::Result<T, errors::ApiErrorResponse> {
|
||||
self.map_err(|err| {
|
||||
let error = match err.current_context() {
|
||||
errors::ConnectorError::ProcessingStepFailed(Some(bytes)) => {
|
||||
let response_str = std::str::from_utf8(bytes);
|
||||
let data = match response_str {
|
||||
Ok(s) => serde_json::from_str(s)
|
||||
.map_err(
|
||||
|error| logger::error!(%error,"Failed to convert response to JSON"),
|
||||
)
|
||||
.ok(),
|
||||
Err(error) => {
|
||||
logger::error!(%error,"Failed to convert response to UTF8 string");
|
||||
None
|
||||
}
|
||||
};
|
||||
errors::ApiErrorResponse::PaymentAuthorizationFailed { data }
|
||||
}
|
||||
errors::ConnectorError::MissingRequiredField { field_name } => {
|
||||
errors::ApiErrorResponse::MissingRequiredField { field_name }
|
||||
}
|
||||
errors::ConnectorError::MissingRequiredFields { field_names } => {
|
||||
errors::ApiErrorResponse::MissingRequiredFields { field_names: field_names.to_vec() }
|
||||
}
|
||||
errors::ConnectorError::NotImplemented(reason) => {
|
||||
errors::ApiErrorResponse::NotImplemented {
|
||||
message: errors::api_error_response::NotImplementedMessage::Reason(
|
||||
reason.to_string(),
|
||||
),
|
||||
}
|
||||
};
|
||||
errors::ApiErrorResponse::PaymentAuthorizationFailed { data }
|
||||
}
|
||||
errors::ConnectorError::MissingRequiredField { field_name } => {
|
||||
errors::ApiErrorResponse::MissingRequiredField { field_name }
|
||||
}
|
||||
errors::ConnectorError::MissingRequiredFields { field_names } => {
|
||||
errors::ApiErrorResponse::MissingRequiredFields { field_names: field_names.to_vec() }
|
||||
}
|
||||
errors::ConnectorError::NotImplemented(reason) => {
|
||||
errors::ApiErrorResponse::NotImplemented {
|
||||
message: errors::api_error_response::NotImplementedMessage::Reason(
|
||||
reason.to_string(),
|
||||
),
|
||||
}
|
||||
}
|
||||
errors::ConnectorError::MismatchedPaymentData => {
|
||||
errors::ApiErrorResponse::InvalidDataValue {
|
||||
field_name:
|
||||
"payment_method_data, payment_method_type and payment_experience does not match",
|
||||
errors::ConnectorError::MismatchedPaymentData => {
|
||||
errors::ApiErrorResponse::InvalidDataValue {
|
||||
field_name:
|
||||
"payment_method_data, payment_method_type and payment_experience does not match",
|
||||
}
|
||||
},
|
||||
errors::ConnectorError::NotSupported { message, connector, payment_experience } => {
|
||||
errors::ApiErrorResponse::NotSupported { message: format!("{message} is not supported by {connector} through payment experience {payment_experience}") }
|
||||
},
|
||||
errors::ConnectorError::FlowNotSupported{ flow, connector } => {
|
||||
errors::ApiErrorResponse::FlowNotSupported { flow: flow.to_owned(), connector: connector.to_owned() }
|
||||
}
|
||||
},
|
||||
errors::ConnectorError::NotSupported { message, connector, payment_experience } => {
|
||||
errors::ApiErrorResponse::NotSupported { message: format!("{message} is not supported by {connector} through payment experience {payment_experience}") }
|
||||
},
|
||||
errors::ConnectorError::FlowNotSupported{ flow, connector } => {
|
||||
errors::ApiErrorResponse::FlowNotSupported { flow: flow.to_owned(), connector: connector.to_owned() }
|
||||
}
|
||||
_ => errors::ApiErrorResponse::InternalServerError,
|
||||
};
|
||||
self.change_context(error)
|
||||
_ => errors::ApiErrorResponse::InternalServerError,
|
||||
};
|
||||
err.change_context(error)
|
||||
})
|
||||
}
|
||||
|
||||
fn to_verify_failed_response(self) -> error_stack::Report<errors::ApiErrorResponse> {
|
||||
let error = self.current_context();
|
||||
let data = match error {
|
||||
errors::ConnectorError::ProcessingStepFailed(Some(bytes)) => {
|
||||
let response_str = std::str::from_utf8(bytes);
|
||||
let error_response = match response_str {
|
||||
Ok(s) => serde_json::from_str(s)
|
||||
.map_err(|err| logger::error!(%err, "Failed to convert response to JSON"))
|
||||
.ok(),
|
||||
Err(err) => {
|
||||
logger::error!(%err, "Failed to convert response to UTF8 string");
|
||||
None
|
||||
fn to_verify_failed_response(self) -> error_stack::Result<T, errors::ApiErrorResponse> {
|
||||
self.map_err(|err| {
|
||||
let error = err.current_context();
|
||||
let data = match error {
|
||||
errors::ConnectorError::ProcessingStepFailed(Some(bytes)) => {
|
||||
let response_str = std::str::from_utf8(bytes);
|
||||
let error_response = match response_str {
|
||||
Ok(s) => serde_json::from_str(s)
|
||||
.map_err(
|
||||
|err| logger::error!(%err, "Failed to convert response to JSON"),
|
||||
)
|
||||
.ok(),
|
||||
Err(err) => {
|
||||
logger::error!(%err, "Failed to convert response to UTF8 string");
|
||||
None
|
||||
}
|
||||
};
|
||||
errors::ApiErrorResponse::PaymentAuthorizationFailed {
|
||||
data: error_response,
|
||||
}
|
||||
};
|
||||
errors::ApiErrorResponse::PaymentAuthorizationFailed {
|
||||
data: error_response,
|
||||
}
|
||||
}
|
||||
errors::ConnectorError::MissingRequiredField { field_name } => {
|
||||
errors::ApiErrorResponse::MissingRequiredField { field_name }
|
||||
}
|
||||
_ => {
|
||||
logger::error!(%error,"Verify flow failed");
|
||||
errors::ApiErrorResponse::PaymentAuthorizationFailed { data: None }
|
||||
}
|
||||
};
|
||||
self.change_context(data)
|
||||
errors::ConnectorError::MissingRequiredField { field_name } => {
|
||||
errors::ApiErrorResponse::MissingRequiredField { field_name }
|
||||
}
|
||||
_ => {
|
||||
logger::error!(%error,"Verify flow failed");
|
||||
errors::ApiErrorResponse::PaymentAuthorizationFailed { data: None }
|
||||
}
|
||||
};
|
||||
err.change_context(data)
|
||||
})
|
||||
}
|
||||
|
||||
fn to_dispute_failed_response(self) -> error_stack::Report<errors::ApiErrorResponse> {
|
||||
let error = match self.current_context() {
|
||||
errors::ConnectorError::ProcessingStepFailed(Some(bytes)) => {
|
||||
let response_str = std::str::from_utf8(bytes);
|
||||
let data = match response_str {
|
||||
Ok(s) => serde_json::from_str(s)
|
||||
.map_err(
|
||||
|error| logger::error!(%error,"Failed to convert response to JSON"),
|
||||
)
|
||||
.ok(),
|
||||
Err(error) => {
|
||||
logger::error!(%error,"Failed to convert response to UTF8 string");
|
||||
None
|
||||
}
|
||||
};
|
||||
errors::ApiErrorResponse::DisputeFailed { data }
|
||||
}
|
||||
errors::ConnectorError::MissingRequiredField { field_name } => {
|
||||
errors::ApiErrorResponse::MissingRequiredField { field_name }
|
||||
}
|
||||
errors::ConnectorError::MissingRequiredFields { field_names } => {
|
||||
errors::ApiErrorResponse::MissingRequiredFields {
|
||||
field_names: field_names.to_vec(),
|
||||
fn to_dispute_failed_response(self) -> error_stack::Result<T, errors::ApiErrorResponse> {
|
||||
self.map_err(|err| {
|
||||
let error = match err.current_context() {
|
||||
errors::ConnectorError::ProcessingStepFailed(Some(bytes)) => {
|
||||
let response_str = std::str::from_utf8(bytes);
|
||||
let data = match response_str {
|
||||
Ok(s) => serde_json::from_str(s)
|
||||
.map_err(
|
||||
|error| logger::error!(%error,"Failed to convert response to JSON"),
|
||||
)
|
||||
.ok(),
|
||||
Err(error) => {
|
||||
logger::error!(%error,"Failed to convert response to UTF8 string");
|
||||
None
|
||||
}
|
||||
};
|
||||
errors::ApiErrorResponse::DisputeFailed { data }
|
||||
}
|
||||
}
|
||||
_ => errors::ApiErrorResponse::InternalServerError,
|
||||
};
|
||||
self.change_context(error)
|
||||
errors::ConnectorError::MissingRequiredField { field_name } => {
|
||||
errors::ApiErrorResponse::MissingRequiredField { field_name }
|
||||
}
|
||||
errors::ConnectorError::MissingRequiredFields { field_names } => {
|
||||
errors::ApiErrorResponse::MissingRequiredFields {
|
||||
field_names: field_names.to_vec(),
|
||||
}
|
||||
}
|
||||
_ => errors::ApiErrorResponse::InternalServerError,
|
||||
};
|
||||
err.change_context(error)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -48,7 +48,7 @@ pub async fn create_connector_customer<F: Clone, T: Clone>(
|
||||
payments::CallConnectorAction::Trigger,
|
||||
)
|
||||
.await
|
||||
.map_err(|error| error.to_payment_failed_response())?;
|
||||
.to_payment_failed_response()?;
|
||||
|
||||
metrics::CONNECTOR_CUSTOMER_CREATE.add(
|
||||
&metrics::CONTEXT,
|
||||
|
||||
@ -140,7 +140,7 @@ impl types::PaymentsAuthorizeRouterData {
|
||||
connector_integration
|
||||
.execute_pretasks(self, state)
|
||||
.await
|
||||
.map_err(|error| error.to_payment_failed_response())?;
|
||||
.to_payment_failed_response()?;
|
||||
|
||||
metrics::EXECUTE_PRETASK_COUNT.add(
|
||||
&metrics::CONTEXT,
|
||||
@ -165,7 +165,7 @@ impl types::PaymentsAuthorizeRouterData {
|
||||
call_connector_action,
|
||||
)
|
||||
.await
|
||||
.map_err(|error| error.to_payment_failed_response())?;
|
||||
.to_payment_failed_response()?;
|
||||
|
||||
let pm_id = tokenization::save_payment_method(
|
||||
state,
|
||||
@ -266,7 +266,7 @@ pub async fn authorize_preprocessing_steps<F: Clone>(
|
||||
payments::CallConnectorAction::Trigger,
|
||||
)
|
||||
.await
|
||||
.map_err(|error| error.to_payment_failed_response())?;
|
||||
.to_payment_failed_response()?;
|
||||
|
||||
metrics::PREPROCESSING_STEPS_COUNT.add(
|
||||
&metrics::CONTEXT,
|
||||
|
||||
@ -96,7 +96,7 @@ impl types::PaymentsCancelRouterData {
|
||||
call_connector_action,
|
||||
)
|
||||
.await
|
||||
.map_err(|error| error.to_payment_failed_response())?;
|
||||
.to_payment_failed_response()?;
|
||||
|
||||
Ok(resp)
|
||||
}
|
||||
|
||||
@ -89,7 +89,7 @@ impl types::PaymentsCaptureRouterData {
|
||||
call_connector_action,
|
||||
)
|
||||
.await
|
||||
.map_err(|error| error.to_payment_failed_response())?;
|
||||
.to_payment_failed_response()?;
|
||||
|
||||
Ok(resp)
|
||||
}
|
||||
|
||||
@ -104,7 +104,7 @@ impl types::PaymentsCompleteAuthorizeRouterData {
|
||||
call_connector_action,
|
||||
)
|
||||
.await
|
||||
.map_err(|error| error.to_payment_failed_response())?;
|
||||
.to_payment_failed_response()?;
|
||||
|
||||
Ok(resp)
|
||||
}
|
||||
|
||||
@ -89,7 +89,7 @@ impl types::PaymentsSyncRouterData {
|
||||
call_connector_action,
|
||||
)
|
||||
.await
|
||||
.map_err(|error| error.to_payment_failed_response())?;
|
||||
.to_payment_failed_response()?;
|
||||
|
||||
Ok(resp)
|
||||
}
|
||||
|
||||
@ -306,7 +306,7 @@ impl types::PaymentsSessionRouterData {
|
||||
call_connector_action,
|
||||
)
|
||||
.await
|
||||
.map_err(|error| error.to_payment_failed_response())?;
|
||||
.to_payment_failed_response()?;
|
||||
|
||||
Ok(resp)
|
||||
}
|
||||
|
||||
@ -133,7 +133,7 @@ impl types::VerifyRouterData {
|
||||
call_connector_action,
|
||||
)
|
||||
.await
|
||||
.map_err(|err| err.to_verify_failed_response())?;
|
||||
.to_verify_failed_response()?;
|
||||
|
||||
let pm_id = tokenization::save_payment_method(
|
||||
state,
|
||||
|
||||
@ -229,7 +229,7 @@ pub async fn add_payment_method_token<F: Clone, T: Clone>(
|
||||
payments::CallConnectorAction::Trigger,
|
||||
)
|
||||
.await
|
||||
.map_err(|error| error.to_payment_failed_response())?;
|
||||
.to_payment_failed_response()?;
|
||||
|
||||
metrics::CONNECTOR_PAYMENT_METHOD_TOKENIZATION.add(
|
||||
&metrics::CONTEXT,
|
||||
|
||||
@ -191,7 +191,7 @@ pub async fn trigger_refund_to_gateway(
|
||||
payments::CallConnectorAction::Trigger,
|
||||
)
|
||||
.await
|
||||
.map_err(|error| error.to_refund_failed_response())?
|
||||
.to_refund_failed_response()?
|
||||
} else {
|
||||
router_data
|
||||
};
|
||||
@ -410,7 +410,7 @@ pub async fn sync_refund_with_gateway(
|
||||
payments::CallConnectorAction::Trigger,
|
||||
)
|
||||
.await
|
||||
.map_err(|error| error.to_refund_failed_response())?
|
||||
.to_refund_failed_response()?
|
||||
} else {
|
||||
router_data
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user