mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-10-29 09:07:09 +08:00
chore: add .attach_printable for InternalServerError (#368)
This commit is contained in:
@ -160,6 +160,10 @@ pub async fn merchant_account_update(
|
||||
}
|
||||
|
||||
let mut response = req.clone();
|
||||
|
||||
let encode_error_handler =
|
||||
|value: &str| format!("Unable to encode to serde_json::Value, {value}");
|
||||
|
||||
let updated_merchant_account = storage::MerchantAccountUpdate::Update {
|
||||
merchant_id: merchant_id.to_string(),
|
||||
merchant_name: req
|
||||
@ -169,7 +173,8 @@ pub async fn merchant_account_update(
|
||||
merchant_details: if req.merchant_details.is_some() {
|
||||
Some(
|
||||
utils::Encode::<api::MerchantDetails>::encode_to_value(&req.merchant_details)
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)?,
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)
|
||||
.attach_printable_lazy(|| encode_error_handler("MerchantDetails"))?,
|
||||
)
|
||||
} else {
|
||||
merchant_account.merchant_details.to_owned()
|
||||
@ -180,7 +185,8 @@ pub async fn merchant_account_update(
|
||||
webhook_details: if req.webhook_details.is_some() {
|
||||
Some(
|
||||
utils::Encode::<api::WebhookDetails>::encode_to_value(&req.webhook_details)
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)?,
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)
|
||||
.attach_printable_lazy(|| encode_error_handler("WebhookDetails"))?,
|
||||
)
|
||||
} else {
|
||||
merchant_account.webhook_details.to_owned()
|
||||
@ -220,7 +226,8 @@ pub async fn merchant_account_update(
|
||||
|
||||
db.update_merchant(merchant_account, updated_merchant_account)
|
||||
.await
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)?;
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)
|
||||
.attach_printable_lazy(|| format!("Failed while updating merchant: {}", merchant_id))?;
|
||||
Ok(service_api::ApplicationResponse::Json(response))
|
||||
}
|
||||
|
||||
@ -297,7 +304,10 @@ pub async fn create_payment_connector(
|
||||
Some(val) => {
|
||||
for pm in val.into_iter() {
|
||||
let pm_value = utils::Encode::<api::PaymentMethods>::encode_to_value(&pm)
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)?;
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)
|
||||
.attach_printable(
|
||||
"Failed while encoding to serde_json::Value, PaymentMethod",
|
||||
)?;
|
||||
vec.push(pm_value)
|
||||
}
|
||||
Some(vec)
|
||||
@ -446,7 +456,13 @@ pub async fn update_payment_connector(
|
||||
let updated_mca = db
|
||||
.update_merchant_connector_account(mca, payment_connector)
|
||||
.await
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)?;
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)
|
||||
.attach_printable_lazy(|| {
|
||||
format!(
|
||||
"Failed while updating MerchantConnectorAccount: id: {}",
|
||||
merchant_connector_id
|
||||
)
|
||||
})?;
|
||||
let response = api::PaymentConnectorCreate {
|
||||
connector_type: updated_mca.connector_type.foreign_into(),
|
||||
connector_name: updated_mca.connector_name,
|
||||
|
||||
@ -54,7 +54,8 @@ pub async fn create_customer(
|
||||
..Default::default()
|
||||
})
|
||||
.await
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)?;
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)
|
||||
.attach_printable("Failed while inserting new address")?;
|
||||
};
|
||||
|
||||
let new_customer = storage::CustomerNew {
|
||||
@ -74,9 +75,17 @@ pub async fn create_customer(
|
||||
if error.current_context().is_db_unique_violation() {
|
||||
db.find_customer_by_customer_id_merchant_id(customer_id, merchant_id)
|
||||
.await
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)?
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)
|
||||
.attach_printable_lazy(|| {
|
||||
format!(
|
||||
"Failed while fetching Customer, customer_id: {}",
|
||||
customer_id
|
||||
)
|
||||
})?
|
||||
} else {
|
||||
Err(error.change_context(errors::ApiErrorResponse::InternalServerError))?
|
||||
Err(error
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)
|
||||
.attach_printable("Failed while inserting new customer"))?
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -252,7 +261,11 @@ pub async fn update_customer(
|
||||
update_address,
|
||||
)
|
||||
.await
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)?;
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)
|
||||
.attach_printable(format!(
|
||||
"Failed while updating address: merchant_id: {}, customer_id: {}",
|
||||
merchant_account.merchant_id, update_customer.customer_id
|
||||
))?;
|
||||
};
|
||||
|
||||
let response = db
|
||||
|
||||
@ -70,7 +70,13 @@ pub async fn get_customer_mandates(
|
||||
.store
|
||||
.find_mandate_by_merchant_id_customer_id(&merchant_account.merchant_id, &req.customer_id)
|
||||
.await
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)?;
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)
|
||||
.attach_printable_lazy(|| {
|
||||
format!(
|
||||
"Failed while finding mandate: merchant_id: {}, customer_id: {}",
|
||||
merchant_account.merchant_id, req.customer_id
|
||||
)
|
||||
})?;
|
||||
|
||||
if mandates.is_empty() {
|
||||
Err(report!(errors::ApiErrorResponse::MandateNotFound).attach_printable("No Mandate found"))
|
||||
|
||||
@ -18,7 +18,7 @@ use crate::{
|
||||
storage::{self, enums},
|
||||
transformers::ForeignInto,
|
||||
},
|
||||
utils::{BytesExt, OptionExt},
|
||||
utils::{BytesExt, ConnectorResponseExt, OptionExt},
|
||||
};
|
||||
|
||||
#[instrument(skip_all)]
|
||||
@ -300,21 +300,15 @@ pub async fn get_card_from_legacy_locker<'a>(
|
||||
let get_card_result = if !locker.mock_locker {
|
||||
let response = services::call_connector_api(state, request)
|
||||
.await
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)?;
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)
|
||||
.attach_printable("Failed while executing call_connector_api for get_card");
|
||||
|
||||
match response {
|
||||
Ok(card) => card
|
||||
.response
|
||||
.parse_struct("AddCardResponse")
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)
|
||||
.attach_printable("Decoding failed for AddCardResponse"),
|
||||
Err(err) => Err(report!(errors::ApiErrorResponse::InternalServerError)
|
||||
.attach_printable(format!("Got 4xx from the locker: {err:?}"))),
|
||||
}?
|
||||
response.get_response_inner("AddCardResponse")?
|
||||
} else {
|
||||
let (get_card_response, _) = mock_get_card(&*state.store, card_id)
|
||||
.await
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)?;
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)
|
||||
.attach_printable("Failed while fetching card from mock_locker")?;
|
||||
get_card_response
|
||||
};
|
||||
|
||||
@ -331,18 +325,17 @@ pub async fn delete_card<'a>(
|
||||
let request = payment_methods::mk_delete_card_request(&state.conf.locker, merchant_id, card_id)
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)
|
||||
.attach_printable("Making Delete card request Failed")?;
|
||||
|
||||
let card_delete_failure_message = "Failed while deleting card from card_locker";
|
||||
let delete_card_resp = if !locker.mock_locker {
|
||||
services::call_connector_api(state, request)
|
||||
.await
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)?
|
||||
.map_err(|_x| errors::ApiErrorResponse::InternalServerError)?
|
||||
.response
|
||||
.parse_struct("DeleteCardResponse")
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)?
|
||||
.get_response_inner("DeleteCardResponse")?
|
||||
} else {
|
||||
mock_delete_card(&*state.store, card_id)
|
||||
.await
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)?
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)
|
||||
.attach_printable(card_delete_failure_message)?
|
||||
};
|
||||
|
||||
Ok(delete_card_resp)
|
||||
@ -805,7 +798,8 @@ pub async fn retrieve_payment_method(
|
||||
let get_card_resp =
|
||||
get_card_from_legacy_locker(state, &locker_id, &pm.payment_method_id).await?;
|
||||
let card_detail = payment_methods::get_card_detail(&pm, get_card_resp.card)
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)?;
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)
|
||||
.attach_printable("Failed while getting card details from locker")?;
|
||||
Some(card_detail)
|
||||
} else {
|
||||
None
|
||||
|
||||
@ -88,7 +88,8 @@ where
|
||||
validate_result.merchant_id,
|
||||
)
|
||||
.await
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)?;
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)
|
||||
.attach_printable("Failed while fetching/creating customer")?;
|
||||
|
||||
let (operation, payment_method_data) = operation
|
||||
.to_domain()?
|
||||
|
||||
@ -467,7 +467,8 @@ where
|
||||
)
|
||||
.await
|
||||
.into_report()
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)?;
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)
|
||||
.attach_printable("Failed while getting process schedule time")?;
|
||||
|
||||
match schedule_time {
|
||||
Some(stime) => {
|
||||
@ -476,6 +477,7 @@ where
|
||||
.await
|
||||
.into_report()
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)
|
||||
.attach_printable("Failed while adding task to process tracker")
|
||||
}
|
||||
None => Ok(()),
|
||||
}
|
||||
|
||||
@ -83,7 +83,8 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::VerifyRequest> for Paym
|
||||
|
||||
let payment_id = payment_id
|
||||
.get_payment_intent_id()
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)?;
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)
|
||||
.attach_printable("Failed while getting payment_intent_id from PaymentIdType")?;
|
||||
|
||||
payment_attempt = match db
|
||||
.insert_payment_attempt(
|
||||
|
||||
@ -234,7 +234,13 @@ async fn get_tracker_for_sync<
|
||||
let refunds = db
|
||||
.find_refund_by_payment_id_merchant_id(&payment_id_str, merchant_id, storage_scheme)
|
||||
.await
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)?;
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)
|
||||
.attach_printable_lazy(|| {
|
||||
format!(
|
||||
"Failed while getting refund list for, payment_id: {}, merchant_id: {}",
|
||||
&payment_id_str, merchant_id
|
||||
)
|
||||
})?;
|
||||
|
||||
Ok((
|
||||
Box::new(operation),
|
||||
|
||||
@ -48,7 +48,8 @@ where
|
||||
let auth_type: types::ConnectorAuthType = merchant_connector_account
|
||||
.connector_account_details
|
||||
.parse_value("ConnectorAuthType")
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)?;
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)
|
||||
.attach_printable("Failed while parsing value for ConnectorAuthType")?;
|
||||
|
||||
payment_method = payment_data
|
||||
.payment_attempt
|
||||
|
||||
@ -163,7 +163,13 @@ pub async fn trigger_refund_to_gateway(
|
||||
merchant_account.storage_scheme,
|
||||
)
|
||||
.await
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)?;
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)
|
||||
.attach_printable_lazy(|| {
|
||||
format!(
|
||||
"Failed while updating refund: refund_id: {}",
|
||||
refund.refund_id
|
||||
)
|
||||
})?;
|
||||
Ok(response)
|
||||
}
|
||||
|
||||
@ -304,7 +310,13 @@ pub async fn sync_refund_with_gateway(
|
||||
merchant_account.storage_scheme,
|
||||
)
|
||||
.await
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)?;
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)
|
||||
.attach_printable_lazy(|| {
|
||||
format!(
|
||||
"Unable to update refund with refund_id: {}",
|
||||
refund.refund_id
|
||||
)
|
||||
})?;
|
||||
Ok(response)
|
||||
}
|
||||
|
||||
@ -335,7 +347,10 @@ pub async fn refund_update_core(
|
||||
merchant_account.storage_scheme,
|
||||
)
|
||||
.await
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)?;
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)
|
||||
.attach_printable_lazy(|| {
|
||||
format!("Unable to update refund with refund_id: {}", refund_id)
|
||||
})?;
|
||||
|
||||
Ok(services::ApplicationResponse::Json(response.foreign_into()))
|
||||
}
|
||||
@ -382,8 +397,13 @@ pub async fn validate_and_create_refund(
|
||||
merchant_account.storage_scheme,
|
||||
)
|
||||
.await
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)?
|
||||
{
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)
|
||||
.attach_printable_lazy(|| {
|
||||
format!(
|
||||
"Unique violation while checking refund_id: {} against merchant_id: {}",
|
||||
refund_id, merchant_account.merchant_id
|
||||
)
|
||||
})? {
|
||||
Some(refund) => refund,
|
||||
None => {
|
||||
let connecter_transaction_id = match &payment_attempt.connector_transaction_id {
|
||||
@ -556,7 +576,8 @@ pub async fn schedule_refund_execution(
|
||||
api_models::refunds::RefundType::Scheduled => {
|
||||
add_refund_execute_task(db, &refund, runner)
|
||||
.await
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)?;
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)
|
||||
.attach_printable_lazy(|| format!("Failed while pushing refund execute task to scheduler, refund_id: {}", refund.refund_id))?;
|
||||
|
||||
Ok(refund)
|
||||
}
|
||||
@ -579,7 +600,8 @@ pub async fn schedule_refund_execution(
|
||||
api_models::refunds::RefundType::Scheduled => {
|
||||
add_refund_sync_task(db, &refund, runner)
|
||||
.await
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)?;
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)
|
||||
.attach_printable_lazy(|| format!("Failed while pushing refund sync task in scheduler: refund_id: {}", refund.refund_id))?;
|
||||
Ok(refund)
|
||||
}
|
||||
api_models::refunds::RefundType::Instant => {
|
||||
@ -797,7 +819,13 @@ pub async fn add_refund_sync_task(
|
||||
let response = db
|
||||
.insert_process(process_tracker_entry)
|
||||
.await
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)?;
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)
|
||||
.attach_printable_lazy(|| {
|
||||
format!(
|
||||
"Failed while inserting task in process_tracker: refund_id: {}",
|
||||
refund.refund_id
|
||||
)
|
||||
})?;
|
||||
Ok(response)
|
||||
}
|
||||
|
||||
@ -832,7 +860,13 @@ pub async fn add_refund_execute_task(
|
||||
let response = db
|
||||
.insert_process(process_tracker_entry)
|
||||
.await
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)?;
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)
|
||||
.attach_printable_lazy(|| {
|
||||
format!(
|
||||
"Failed while inserting task in process_tracker: refund_id: {}",
|
||||
refund.refund_id
|
||||
)
|
||||
})?;
|
||||
Ok(response)
|
||||
}
|
||||
|
||||
|
||||
@ -107,7 +107,9 @@ pub async fn validate_uniqueness_of_refund_id_against_merchant_id(
|
||||
// to be on the safer side. Fixed this, now vector is not returned but should check the flow in detail later.
|
||||
Ok(None)
|
||||
} else {
|
||||
Err(err.change_context(errors::ApiErrorResponse::InternalServerError))
|
||||
Err(err
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)
|
||||
.attach_printable("Failed while finding refund, database error"))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -126,8 +126,8 @@ impl ConnectorData {
|
||||
let connector_name = api_enums::Connector::from_str(name)
|
||||
.into_report()
|
||||
.change_context(errors::ConnectorError::InvalidConnectorName)
|
||||
.attach_printable_lazy(|| format!("unable to parse connector name {connector:?}"))
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)?;
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)
|
||||
.attach_printable_lazy(|| format!("unable to parse connector name {connector:?}"))?;
|
||||
Ok(Self {
|
||||
connector,
|
||||
connector_name,
|
||||
|
||||
@ -60,7 +60,8 @@ impl MandateResponseExt for MandateResponse {
|
||||
.await?;
|
||||
let card_detail =
|
||||
payment_methods::transformers::get_card_detail(&payment_method, get_card_resp.card)
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)?;
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)
|
||||
.attach_printable("Failed while getting card details")?;
|
||||
Some(MandateCardDetails::from(card_detail).into_inner())
|
||||
} else {
|
||||
None
|
||||
|
||||
@ -11,10 +11,16 @@ pub(crate) use common_utils::{
|
||||
fp_utils::when,
|
||||
validation::validate_email,
|
||||
};
|
||||
use error_stack::{IntoReport, ResultExt};
|
||||
use nanoid::nanoid;
|
||||
use serde::de::DeserializeOwned;
|
||||
|
||||
pub(crate) use self::ext_traits::{OptionExt, ValidateCall};
|
||||
use crate::consts;
|
||||
use crate::{
|
||||
consts,
|
||||
core::errors::{self, RouterResult},
|
||||
logger, types,
|
||||
};
|
||||
|
||||
pub mod error_parser {
|
||||
use std::fmt::Display;
|
||||
@ -67,3 +73,50 @@ pub mod error_parser {
|
||||
pub fn generate_id(length: usize, prefix: &str) -> String {
|
||||
format!("{}_{}", prefix, nanoid!(length, &consts::ALPHABETS))
|
||||
}
|
||||
|
||||
pub trait ConnectorResponseExt: Sized {
|
||||
fn get_response(self) -> RouterResult<types::Response>;
|
||||
fn get_error_response(self) -> RouterResult<types::Response>;
|
||||
fn get_response_inner<T: DeserializeOwned>(self, type_name: &str) -> RouterResult<T> {
|
||||
self.get_response()?
|
||||
.response
|
||||
.parse_struct(type_name)
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)
|
||||
}
|
||||
}
|
||||
|
||||
impl<E> ConnectorResponseExt
|
||||
for Result<Result<types::Response, types::Response>, error_stack::Report<E>>
|
||||
{
|
||||
fn get_error_response(self) -> RouterResult<types::Response> {
|
||||
self.change_context(errors::ApiErrorResponse::InternalServerError)
|
||||
.attach_printable("Error while receiving response")
|
||||
.and_then(|inner| match inner {
|
||||
Ok(res) => {
|
||||
logger::error!(response=?res);
|
||||
Err(errors::ApiErrorResponse::InternalServerError)
|
||||
.into_report()
|
||||
.attach_printable(format!(
|
||||
"Expecting error response, received response: {res:?}"
|
||||
))
|
||||
}
|
||||
Err(err_res) => Ok(err_res),
|
||||
})
|
||||
}
|
||||
|
||||
fn get_response(self) -> RouterResult<types::Response> {
|
||||
self.change_context(errors::ApiErrorResponse::InternalServerError)
|
||||
.attach_printable("Error while receiving response")
|
||||
.and_then(|inner| match inner {
|
||||
Err(err_res) => {
|
||||
logger::error!(error_response=?err_res);
|
||||
Err(errors::ApiErrorResponse::InternalServerError)
|
||||
.into_report()
|
||||
.attach_printable(format!(
|
||||
"Expecting response, received error response: {err_res:?}"
|
||||
))
|
||||
}
|
||||
Ok(res) => Ok(res),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user