From 4f0c788cf26907e2be784978c412081a93386d04 Mon Sep 17 00:00:00 2001 From: Hrithikesh <61539176+hrithikesh026@users.noreply.github.com> Date: Tue, 26 Mar 2024 17:04:46 +0530 Subject: [PATCH 01/20] fix(core): make eci in AuthenticationData optional (#4187) --- crates/router/src/connector/checkout/transformers.rs | 2 +- crates/router/src/core/payments/types.rs | 10 ++-------- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/crates/router/src/connector/checkout/transformers.rs b/crates/router/src/connector/checkout/transformers.rs index 8004b3b5a12..64fddca13b5 100644 --- a/crates/router/src/connector/checkout/transformers.rs +++ b/crates/router/src/connector/checkout/transformers.rs @@ -391,7 +391,7 @@ impl TryFrom<&CheckoutRouterData<&types::PaymentsAuthorizeRouterData>> for Payme enums::AuthenticationType::ThreeDs => CheckoutThreeDS { enabled: true, force_3ds: true, - eci: authentication_data.map(|auth| auth.eci.clone()), + eci: authentication_data.and_then(|auth| auth.eci.clone()), cryptogram: authentication_data.map(|auth| auth.cavv.clone()), xid: authentication_data.map(|auth| auth.threeds_server_transaction_id.clone()), version: authentication_data.map(|auth| auth.message_version.clone()), diff --git a/crates/router/src/core/payments/types.rs b/crates/router/src/core/payments/types.rs index 6e33b2f60e4..ac54e1b7aa3 100644 --- a/crates/router/src/core/payments/types.rs +++ b/crates/router/src/core/payments/types.rs @@ -379,7 +379,7 @@ impl SurchargeMetadata { #[derive(Debug, Clone)] pub struct AuthenticationData { - pub eci: String, + pub eci: Option, pub cavv: String, pub threeds_server_transaction_id: String, pub message_version: String, @@ -409,14 +409,8 @@ impl ForeignTryFrom<&storage::Authentication> for AuthenticationData { .get_required_value("cavv") .change_context(errors::ApiErrorResponse::InternalServerError) .attach_printable("cavv must not be null when authentication_status is success")?; - let eci = authentication - .eci - .clone() - .get_required_value("eci") - .change_context(errors::ApiErrorResponse::InternalServerError) - .attach_printable("eci must not be null when authentication_status is success")?; Ok(Self { - eci, + eci: authentication.eci.clone(), cavv, threeds_server_transaction_id, message_version: message_version.to_string(), From 84bef251480a77027b43c3dc91353a0cb40d5ff1 Mon Sep 17 00:00:00 2001 From: Prasunna Soppa <70575890+prasunna09@users.noreply.github.com> Date: Tue, 26 Mar 2024 18:39:37 +0530 Subject: [PATCH 02/20] fix(connector): [Trustpay] fix deserialization error for incoming webhook response for trustpay and add error code mapping '800.100.203' (#4199) Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com> --- crates/router/src/connector/trustpay.rs | 2 +- .../src/connector/trustpay/transformers.rs | 47 +++++++++++++++---- 2 files changed, 39 insertions(+), 10 deletions(-) diff --git a/crates/router/src/connector/trustpay.rs b/crates/router/src/connector/trustpay.rs index 18775dd3981..116cea9e239 100644 --- a/crates/router/src/connector/trustpay.rs +++ b/crates/router/src/connector/trustpay.rs @@ -983,7 +983,7 @@ impl api::IncomingWebhook for Trustpay { dispute_stage: api_models::enums::DisputeStage::Dispute, connector_dispute_id, connector_reason: reason.reason.reject_reason, - connector_reason_code: Some(reason.reason.code), + connector_reason_code: reason.reason.code, challenge_required_by: None, connector_status: payment_info.status.to_string(), created_at: None, diff --git a/crates/router/src/connector/trustpay/transformers.rs b/crates/router/src/connector/trustpay/transformers.rs index 5c5227aedc4..9d5d2e3d749 100644 --- a/crates/router/src/connector/trustpay/transformers.rs +++ b/crates/router/src/connector/trustpay/transformers.rs @@ -112,7 +112,7 @@ pub struct Amount { #[derive(Default, Debug, Serialize, Deserialize, Eq, PartialEq, Clone)] #[serde(rename_all = "PascalCase")] pub struct Reason { - pub code: String, + pub code: Option, pub reject_reason: Option, } @@ -510,6 +510,7 @@ fn is_payment_failed(payment_status: &str) -> (bool, &'static str) { "800.100.172" => (true, "Transaction declined (account blocked)"), "800.100.190" => (true, "Transaction declined (invalid configuration data)"), "800.100.202" => (true, "Account Closed"), + "800.100.203" => (true, "Insufficient Funds"), "800.120.100" => (true, "Rejected by throttling"), "800.300.102" => (true, "Country blacklisted"), "800.300.401" => (true, "Bin blacklisted"), @@ -823,9 +824,16 @@ fn handle_bank_redirects_sync_response( .status_reason_information .unwrap_or_default(); Some(types::ErrorResponse { - code: reason_info.reason.code.clone(), + code: reason_info + .reason + .code + .clone() + .unwrap_or(consts::NO_ERROR_CODE.to_string()), // message vary for the same code, so relying on code alone as it is unique - message: reason_info.reason.code, + message: reason_info + .reason + .code + .unwrap_or(consts::NO_ERROR_MESSAGE.to_string()), reason: reason_info.reason.reject_reason, status_code, attempt_status: None, @@ -875,9 +883,16 @@ pub fn handle_webhook_response( .status_reason_information .unwrap_or_default(); Some(types::ErrorResponse { - code: reason_info.reason.code.clone(), + code: reason_info + .reason + .code + .clone() + .unwrap_or(consts::NO_ERROR_CODE.to_string()), // message vary for the same code, so relying on code alone as it is unique - message: reason_info.reason.code, + message: reason_info + .reason + .code + .unwrap_or(consts::NO_ERROR_MESSAGE.to_string()), reason: reason_info.reason.reject_reason, status_code, attempt_status: None, @@ -1483,9 +1498,16 @@ fn handle_webhooks_refund_response( let error = if utils::is_refund_failure(refund_status) { let reason_info = response.status_reason_information.unwrap_or_default(); Some(types::ErrorResponse { - code: reason_info.reason.code.clone(), + code: reason_info + .reason + .code + .clone() + .unwrap_or(consts::NO_ERROR_CODE.to_string()), // message vary for the same code, so relying on code alone as it is unique - message: reason_info.reason.code, + message: reason_info + .reason + .code + .unwrap_or(consts::NO_ERROR_MESSAGE.to_string()), reason: reason_info.reason.reject_reason, status_code, attempt_status: None, @@ -1540,9 +1562,16 @@ fn handle_bank_redirects_refund_sync_response( .status_reason_information .unwrap_or_default(); Some(types::ErrorResponse { - code: reason_info.reason.code.clone(), + code: reason_info + .reason + .code + .clone() + .unwrap_or(consts::NO_ERROR_CODE.to_string()), // message vary for the same code, so relying on code alone as it is unique - message: reason_info.reason.code, + message: reason_info + .reason + .code + .unwrap_or(consts::NO_ERROR_MESSAGE.to_string()), reason: reason_info.reason.reject_reason, status_code, attempt_status: None, From 0429399c29f76c97bf2096bbe9e9b429c025e56b Mon Sep 17 00:00:00 2001 From: DEEPANSHU BANSAL <41580413+deepanshu-iiitu@users.noreply.github.com> Date: Tue, 26 Mar 2024 19:49:25 +0530 Subject: [PATCH 03/20] fix(connector): [CRYPTOPAY] Skip metadata serialization if none (#4205) --- crates/router/src/connector/cryptopay/transformers.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/router/src/connector/cryptopay/transformers.rs b/crates/router/src/connector/cryptopay/transformers.rs index 635d4a66c26..707cfd8f06b 100644 --- a/crates/router/src/connector/cryptopay/transformers.rs +++ b/crates/router/src/connector/cryptopay/transformers.rs @@ -49,6 +49,7 @@ pub struct CryptopayPaymentsRequest { pay_currency: String, success_redirect_url: Option, unsuccess_redirect_url: Option, + #[serde(skip_serializing_if = "Option::is_none")] metadata: Option, custom_id: String, } From 7f5ad621a18bdf8fa57e51aa3d8c478756ac7da1 Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 27 Mar 2024 00:14:05 +0000 Subject: [PATCH 04/20] chore(version): 2024.03.27.0 --- CHANGELOG.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c4b683bada5..69d68df55c4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,19 @@ All notable changes to HyperSwitch will be documented here. - - - +## 2024.03.27.0 + +### Bug Fixes + +- **connector:** + - [Trustpay] fix deserialization error for incoming webhook response for trustpay and add error code mapping '800.100.203' ([#4199](https://github.com/juspay/hyperswitch/pull/4199)) ([`84bef25`](https://github.com/juspay/hyperswitch/commit/84bef251480a77027b43c3dc91353a0cb40d5ff1)) + - [CRYPTOPAY] Skip metadata serialization if none ([#4205](https://github.com/juspay/hyperswitch/pull/4205)) ([`0429399`](https://github.com/juspay/hyperswitch/commit/0429399c29f76c97bf2096bbe9e9b429c025e56b)) +- **core:** Make eci in AuthenticationData optional ([#4187](https://github.com/juspay/hyperswitch/pull/4187)) ([`4f0c788`](https://github.com/juspay/hyperswitch/commit/4f0c788cf26907e2be784978c412081a93386d04)) + +**Full Changelog:** [`2024.03.26.0...2024.03.27.0`](https://github.com/juspay/hyperswitch/compare/2024.03.26.0...2024.03.27.0) + +- - - + ## 2024.03.26.0 ### Features From 070622125f49c4cc9c35f5ba9c634f1fef6b26d2 Mon Sep 17 00:00:00 2001 From: Shankar Singh C <83439957+ShankarSinghC@users.noreply.github.com> Date: Wed, 27 Mar 2024 11:46:22 +0530 Subject: [PATCH 05/20] fix(log): adding span metadata to `tokio` spawned futures (#4118) --- crates/common_utils/src/macros.rs | 7 --- crates/diesel_models/src/lib.rs | 1 - crates/diesel_models/src/macros.rs | 6 --- crates/drainer/src/handler.rs | 24 ++++++---- crates/drainer/src/lib.rs | 8 +++- crates/router/src/bin/scheduler.rs | 23 ++++++---- .../src/core/payments/flows/authorize_flow.rs | 45 +++++++++++-------- .../payments/operations/payment_confirm.rs | 45 +++++++++++-------- crates/router/src/lib.rs | 3 +- crates/router/tests/utils.rs | 3 +- crates/scheduler/src/consumer.rs | 8 +++- crates/scheduler/src/producer.rs | 8 +++- crates/storage_impl/src/redis.rs | 22 +++++---- 13 files changed, 117 insertions(+), 86 deletions(-) delete mode 100644 crates/diesel_models/src/macros.rs diff --git a/crates/common_utils/src/macros.rs b/crates/common_utils/src/macros.rs index c07b2112db2..b8d5743d8fe 100644 --- a/crates/common_utils/src/macros.rs +++ b/crates/common_utils/src/macros.rs @@ -47,13 +47,6 @@ macro_rules! newtype { }; } -#[macro_export] -macro_rules! async_spawn { - ($t:block) => { - tokio::spawn(async move { $t }); - }; -} - /// Use this to ensure that the corresponding /// openapi route has been implemented in the openapi crate #[macro_export] diff --git a/crates/diesel_models/src/lib.rs b/crates/diesel_models/src/lib.rs index c93306f49d2..24df19ff737 100644 --- a/crates/diesel_models/src/lib.rs +++ b/crates/diesel_models/src/lib.rs @@ -24,7 +24,6 @@ pub mod gsm; #[cfg(feature = "kv_store")] pub mod kv; pub mod locker_mock_up; -pub mod macros; pub mod mandate; pub mod merchant_account; pub mod merchant_connector_account; diff --git a/crates/diesel_models/src/macros.rs b/crates/diesel_models/src/macros.rs deleted file mode 100644 index de3596ecc10..00000000000 --- a/crates/diesel_models/src/macros.rs +++ /dev/null @@ -1,6 +0,0 @@ -#[macro_export] -macro_rules! async_spawn { - ($t:block) => { - tokio::spawn(async move { $t }); - }; -} diff --git a/crates/drainer/src/handler.rs b/crates/drainer/src/handler.rs index 5aa902d84c5..47b60db80d5 100644 --- a/crates/drainer/src/handler.rs +++ b/crates/drainer/src/handler.rs @@ -1,5 +1,6 @@ use std::sync::{atomic, Arc}; +use router_env::tracing::Instrument; use tokio::{ sync::{mpsc, oneshot}, time::{self, Duration}, @@ -68,13 +69,16 @@ impl Handler { while self.running.load(atomic::Ordering::SeqCst) { metrics::DRAINER_HEALTH.add(&metrics::CONTEXT, 1, &[]); if self.store.is_stream_available(stream_index).await { - tokio::spawn(drainer_handler( - self.store.clone(), - stream_index, - self.conf.max_read_count, - self.active_tasks.clone(), - jobs_picked.clone(), - )); + let _task_handle = tokio::spawn( + drainer_handler( + self.store.clone(), + stream_index, + self.conf.max_read_count, + self.active_tasks.clone(), + jobs_picked.clone(), + ) + .in_current_span(), + ); } stream_index = utils::increment_stream_index( (stream_index, jobs_picked.clone()), @@ -116,10 +120,12 @@ impl Handler { let redis_conn_clone = self.store.redis_conn.clone(); // Spawn a task to monitor if redis is down or not - tokio::spawn(async move { redis_conn_clone.on_error(redis_error_tx).await }); + let _task_handle = tokio::spawn( + async move { redis_conn_clone.on_error(redis_error_tx).await }.in_current_span(), + ); //Spawns a task to send shutdown signal if redis goes down - tokio::spawn(redis_error_receiver(redis_error_rx, tx)); + let _task_handle = tokio::spawn(redis_error_receiver(redis_error_rx, tx).in_current_span()); Ok(()) } diff --git a/crates/drainer/src/lib.rs b/crates/drainer/src/lib.rs index 0ed6183faef..e7ae7621365 100644 --- a/crates/drainer/src/lib.rs +++ b/crates/drainer/src/lib.rs @@ -18,7 +18,10 @@ use common_utils::signals::get_allowed_signals; use diesel_models::kv; use error_stack::{IntoReport, ResultExt}; use hyperswitch_interfaces::secrets_interface::secret_state::RawSecret; -use router_env::{instrument, tracing}; +use router_env::{ + instrument, + tracing::{self, Instrument}, +}; use tokio::sync::mpsc; pub(crate) type Settings = crate::settings::Settings; @@ -39,7 +42,8 @@ pub async fn start_drainer(store: Arc, conf: DrainerSettings) -> errors:: "Failed while getting allowed signals".to_string(), ))?; let handle = signal.handle(); - let task_handle = tokio::spawn(common_utils::signals::signal_handler(signal, tx.clone())); + let task_handle = + tokio::spawn(common_utils::signals::signal_handler(signal, tx.clone()).in_current_span()); let handler_clone = drainer_handler.clone(); diff --git a/crates/router/src/bin/scheduler.rs b/crates/router/src/bin/scheduler.rs index c586bfecdb7..1df37e9f6d1 100644 --- a/crates/router/src/bin/scheduler.rs +++ b/crates/router/src/bin/scheduler.rs @@ -16,7 +16,10 @@ use router::{ services::{self, api}, workflows, }; -use router_env::{instrument, tracing}; +use router_env::{ + instrument, + tracing::{self, Instrument}, +}; use scheduler::{ consumer::workflows::ProcessTrackerWorkflow, errors::ProcessTrackerError, workflows::ProcessTrackerWorkflows, SchedulerAppState, @@ -49,10 +52,9 @@ async fn main() -> CustomResult<(), ProcessTrackerError> { .await; // channel to shutdown scheduler gracefully let (tx, rx) = mpsc::channel(1); - tokio::spawn(router::receiver_for_error( - redis_shutdown_signal_rx, - tx.clone(), - )); + let _task_handle = tokio::spawn( + router::receiver_for_error(redis_shutdown_signal_rx, tx.clone()).in_current_span(), + ); #[allow(clippy::expect_used)] let scheduler_flow_str = @@ -81,10 +83,13 @@ async fn main() -> CustomResult<(), ProcessTrackerError> { .await .expect("Failed to create the server"); - tokio::spawn(async move { - let _ = web_server.await; - logger::error!("The health check probe stopped working!"); - }); + let _task_handle = tokio::spawn( + async move { + let _ = web_server.await; + logger::error!("The health check probe stopped working!"); + } + .in_current_span(), + ); logger::debug!(startup_config=?state.conf); diff --git a/crates/router/src/core/payments/flows/authorize_flow.rs b/crates/router/src/core/payments/flows/authorize_flow.rs index efc0e8852da..7757313d867 100644 --- a/crates/router/src/core/payments/flows/authorize_flow.rs +++ b/crates/router/src/core/payments/flows/authorize_flow.rs @@ -1,5 +1,6 @@ use async_trait::async_trait; use error_stack; +use router_env::tracing::Instrument; use super::{ConstructFlowSpecificData, Feature}; use crate::{ @@ -125,26 +126,32 @@ impl Feature for types::PaymentsAu let state = state.clone(); logger::info!("Call to save_payment_method in locker"); - tokio::spawn(async move { - logger::info!("Starting async call to save_payment_method in locker"); - - let result = Box::pin(tokenization::save_payment_method( - &state, - &connector, - response, - &maybe_customer, - &merchant_account, - self.request.payment_method_type, - &key_store, - Some(resp.request.amount), - Some(resp.request.currency), - )) - .await; - - if let Err(err) = result { - logger::error!("Asynchronously saving card in locker failed : {:?}", err); + let _task_handle = tokio::spawn( + async move { + logger::info!("Starting async call to save_payment_method in locker"); + + let result = Box::pin(tokenization::save_payment_method( + &state, + &connector, + response, + &maybe_customer, + &merchant_account, + self.request.payment_method_type, + &key_store, + Some(resp.request.amount), + Some(resp.request.currency), + )) + .await; + + if let Err(err) = result { + logger::error!( + "Asynchronously saving card in locker failed : {:?}", + err + ); + } } - }); + .in_current_span(), + ); Ok(resp) } diff --git a/crates/router/src/core/payments/operations/payment_confirm.rs b/crates/router/src/core/payments/operations/payment_confirm.rs index 2ab98ae124b..cb4226bcfbe 100644 --- a/crates/router/src/core/payments/operations/payment_confirm.rs +++ b/crates/router/src/core/payments/operations/payment_confirm.rs @@ -160,18 +160,21 @@ impl let store = state.store.clone(); - let business_profile_fut = tokio::spawn(async move { - store - .find_business_profile_by_profile_id(&profile_id) - .map(|business_profile_result| { - business_profile_result.to_not_found_response( - errors::ApiErrorResponse::BusinessProfileNotFound { - id: profile_id.to_string(), - }, - ) - }) - .await - }); + let business_profile_fut = tokio::spawn( + async move { + store + .find_business_profile_by_profile_id(&profile_id) + .map(|business_profile_result| { + business_profile_result.to_not_found_response( + errors::ApiErrorResponse::BusinessProfileNotFound { + id: profile_id.to_string(), + }, + ) + }) + .await + } + .in_current_span(), + ); let store = state.store.clone(); @@ -498,13 +501,17 @@ impl let store = state.clone().store; - let additional_pm_data_fut = tokio::spawn(async move { - Ok(n_request_payment_method_data - .async_map(|payment_method_data| async move { - helpers::get_additional_payment_data(&payment_method_data, store.as_ref()).await - }) - .await) - }); + let additional_pm_data_fut = tokio::spawn( + async move { + Ok(n_request_payment_method_data + .async_map(|payment_method_data| async move { + helpers::get_additional_payment_data(&payment_method_data, store.as_ref()) + .await + }) + .await) + } + .in_current_span(), + ); let store = state.clone().store; diff --git a/crates/router/src/lib.rs b/crates/router/src/lib.rs index cc4adca77c9..a8d6e792f3c 100644 --- a/crates/router/src/lib.rs +++ b/crates/router/src/lib.rs @@ -31,6 +31,7 @@ use actix_web::{ }; use http::StatusCode; use hyperswitch_interfaces::secrets_interface::secret_state::SecuredSecret; +use router_env::tracing::Instrument; use routes::AppState; use storage_impl::errors::ApplicationResult; use tokio::sync::{mpsc, oneshot}; @@ -192,7 +193,7 @@ pub async fn start_server(conf: settings::Settings) -> Applicatio .workers(server.workers) .shutdown_timeout(server.shutdown_timeout) .run(); - tokio::spawn(receiver_for_error(rx, server.handle())); + let _task_handle = tokio::spawn(receiver_for_error(rx, server.handle()).in_current_span()); Ok(server) } diff --git a/crates/router/tests/utils.rs b/crates/router/tests/utils.rs index e1ab3e80f32..5d48d6e8ad0 100644 --- a/crates/router/tests/utils.rs +++ b/crates/router/tests/utils.rs @@ -12,6 +12,7 @@ use actix_web::{ }; use derive_deref::Deref; use router::{configs::settings::Settings, routes::AppState, services}; +use router_env::tracing::Instrument; use serde::{de::DeserializeOwned, Deserialize}; use serde_json::{json, Value}; use tokio::sync::{oneshot, OnceCell}; @@ -24,7 +25,7 @@ async fn spawn_server() -> bool { .await .expect("failed to create server"); - let _server = tokio::spawn(server); + let _server = tokio::spawn(server.in_current_span()); true } diff --git a/crates/scheduler/src/consumer.rs b/crates/scheduler/src/consumer.rs index e069db28da7..471f689ffc8 100644 --- a/crates/scheduler/src/consumer.rs +++ b/crates/scheduler/src/consumer.rs @@ -10,7 +10,10 @@ pub use diesel_models::{self, process_tracker as storage}; use error_stack::{IntoReport, ResultExt}; use futures::future; use redis_interface::{RedisConnectionPool, RedisEntryId}; -use router_env::{instrument, tracing}; +use router_env::{ + instrument, + tracing::{self, Instrument}, +}; use time::PrimitiveDateTime; use tokio::sync::mpsc; use uuid::Uuid; @@ -64,7 +67,8 @@ pub async fn start_consumer( .into_report() .attach_printable("Failed while creating a signals handler")?; let handle = signal.handle(); - let task_handle = tokio::spawn(common_utils::signals::signal_handler(signal, tx)); + let task_handle = + tokio::spawn(common_utils::signals::signal_handler(signal, tx).in_current_span()); 'consumer: loop { match rx.try_recv() { diff --git a/crates/scheduler/src/producer.rs b/crates/scheduler/src/producer.rs index bcf37cdf6f2..b8081c2b9ae 100644 --- a/crates/scheduler/src/producer.rs +++ b/crates/scheduler/src/producer.rs @@ -3,7 +3,10 @@ use std::sync::Arc; use common_utils::errors::CustomResult; use diesel_models::enums::ProcessTrackerStatus; use error_stack::{report, IntoReport, ResultExt}; -use router_env::{instrument, tracing}; +use router_env::{ + instrument, + tracing::{self, Instrument}, +}; use time::Duration; use tokio::sync::mpsc; @@ -57,7 +60,8 @@ where .into_report() .attach_printable("Failed while creating a signals handler")?; let handle = signal.handle(); - let task_handle = tokio::spawn(common_utils::signals::signal_handler(signal, tx)); + let task_handle = + tokio::spawn(common_utils::signals::signal_handler(signal, tx).in_current_span()); loop { match rx.try_recv() { diff --git a/crates/storage_impl/src/redis.rs b/crates/storage_impl/src/redis.rs index e4e0c021ac8..be82d4cc293 100644 --- a/crates/storage_impl/src/redis.rs +++ b/crates/storage_impl/src/redis.rs @@ -6,7 +6,7 @@ use std::sync::{atomic, Arc}; use error_stack::{IntoReport, ResultExt}; use redis_interface::PubsubInterface; -use router_env::logger; +use router_env::{logger, tracing::Instrument}; use self::{kv_store::RedisConnInterface, pub_sub::PubSubInterface}; @@ -35,9 +35,12 @@ impl RedisStore { pub fn set_error_callback(&self, callback: tokio::sync::oneshot::Sender<()>) { let redis_clone = self.redis_conn.clone(); - tokio::spawn(async move { - redis_clone.on_error(callback).await; - }); + let _task_handle = tokio::spawn( + async move { + redis_clone.on_error(callback).await; + } + .in_current_span(), + ); } pub async fn subscribe_to_channel( @@ -54,11 +57,14 @@ impl RedisStore { .change_context(redis_interface::errors::RedisError::SubscribeError)?; let redis_clone = self.redis_conn.clone(); - tokio::spawn(async move { - if let Err(e) = redis_clone.on_message().await { - logger::error!(pubsub_err=?e); + let _task_handle = tokio::spawn( + async move { + if let Err(e) = redis_clone.on_message().await { + logger::error!(pubsub_err=?e); + } } - }); + .in_current_span(), + ); Ok(()) } } From 929848f8713b45daf479ba24fb0a49b8e327b6fd Mon Sep 17 00:00:00 2001 From: AkshayaFoiger <131388445+AkshayaFoiger@users.noreply.github.com> Date: Wed, 27 Mar 2024 11:47:30 +0530 Subject: [PATCH 06/20] fix(connectors): fix wallet token deserialization error (#4133) Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com> --- .../router/src/compatibility/stripe/errors.rs | 10 ++++++++ .../connector/bankofamerica/transformers.rs | 7 +++++- .../src/connector/bluesnap/transformers.rs | 9 ++++--- .../braintree_graphql_transformers.rs | 15 ++++++----- .../src/connector/checkout/transformers.rs | 11 +++++--- .../src/connector/cybersource/transformers.rs | 13 +++++++--- .../src/connector/globalpay/transformers.rs | 2 +- .../src/connector/mollie/transformers.rs | 7 +++++- .../src/connector/nexinets/transformers.rs | 2 +- .../router/src/connector/noon/transformers.rs | 3 ++- .../src/connector/payme/transformers.rs | 7 +++--- .../src/connector/square/transformers.rs | 7 +++--- .../router/src/connector/stax/transformers.rs | 13 +++++----- .../src/connector/stripe/transformers.rs | 20 +++++++++------ crates/router/src/connector/utils.rs | 25 +++++++++++++------ .../router/src/connector/zen/transformers.rs | 8 ++++-- crates/router/src/core/errors.rs | 20 +++++++++++++-- .../src/core/errors/api_error_response.rs | 6 ++++- crates/router/src/core/errors/transformers.rs | 5 ++++ crates/router/src/core/errors/utils.rs | 10 +++++--- crates/router/src/core/payments/helpers.rs | 6 +++-- crates/storage_impl/src/errors.rs | 2 +- 22 files changed, 147 insertions(+), 61 deletions(-) diff --git a/crates/router/src/compatibility/stripe/errors.rs b/crates/router/src/compatibility/stripe/errors.rs index 60f4391bdf2..0181ec4e799 100644 --- a/crates/router/src/compatibility/stripe/errors.rs +++ b/crates/router/src/compatibility/stripe/errors.rs @@ -51,6 +51,12 @@ pub enum StripeErrorCode { #[error(error_type = StripeErrorType::CardError, code = "invalid_card_type", message = "Card data is invalid")] InvalidCardType, + #[error( + error_type = StripeErrorType::ConnectorError, code = "invalid_wallet_token", + message = "Invalid {wallet_name} wallet token" + )] + InvalidWalletToken { wallet_name: String }, + #[error(error_type = StripeErrorType::ApiError, code = "refund_failed", message = "refund has failed")] RefundFailed, // stripe error code @@ -625,6 +631,9 @@ impl From for StripeErrorCode { } errors::ApiErrorResponse::CurrencyConversionFailed => Self::CurrencyConversionFailed, errors::ApiErrorResponse::PaymentMethodDeleteFailed => Self::PaymentMethodDeleteFailed, + errors::ApiErrorResponse::InvalidWalletToken { wallet_name } => { + Self::InvalidWalletToken { wallet_name } + } } } } @@ -671,6 +680,7 @@ impl actix_web::ResponseError for StripeErrorCode { | Self::PaymentIntentInvalidParameter { .. } | Self::SerdeQsError { .. } | Self::InvalidRequestData { .. } + | Self::InvalidWalletToken { .. } | Self::PreconditionFailed { .. } | Self::DuplicateMandate | Self::SuccessfulPaymentNotFound diff --git a/crates/router/src/connector/bankofamerica/transformers.rs b/crates/router/src/connector/bankofamerica/transformers.rs index b9a14321025..b4b8ce87ec8 100644 --- a/crates/router/src/connector/bankofamerica/transformers.rs +++ b/crates/router/src/connector/bankofamerica/transformers.rs @@ -22,6 +22,7 @@ use crate::{ transformers::ForeignFrom, ApplePayPredecryptData, }, + unimplemented_payment_method, }; pub struct BankOfAmericaAuthType { @@ -708,7 +709,11 @@ impl TryFrom<&BankOfAmericaRouterData<&types::PaymentsAuthorizeRouterData>> Self::try_from((item, decrypt_data, apple_pay_data)) } types::PaymentMethodToken::Token(_) => { - Err(errors::ConnectorError::InvalidWalletToken)? + Err(unimplemented_payment_method!( + "Apple Pay", + "Manual", + "Bank Of America" + ))? } }, None => { diff --git a/crates/router/src/connector/bluesnap/transformers.rs b/crates/router/src/connector/bluesnap/transformers.rs index 24cc3069f3d..a48e38705c4 100644 --- a/crates/router/src/connector/bluesnap/transformers.rs +++ b/crates/router/src/connector/bluesnap/transformers.rs @@ -310,14 +310,15 @@ impl TryFrom<&BluesnapRouterData<&types::PaymentsAuthorizeRouterData>> for Blues )) } api_models::payments::WalletData::ApplePay(payment_method_data) => { - let apple_pay_payment_data = payment_method_data - .get_applepay_decoded_payment_data() - .change_context(errors::ConnectorError::RequestEncodingFailed)?; + let apple_pay_payment_data = + payment_method_data.get_applepay_decoded_payment_data()?; let apple_pay_payment_data: ApplePayEncodedPaymentData = apple_pay_payment_data .expose()[..] .as_bytes() .parse_struct("ApplePayEncodedPaymentData") - .change_context(errors::ConnectorError::RequestEncodingFailed)?; + .change_context(errors::ConnectorError::InvalidWalletToken { + wallet_name: "Apple Pay".to_string(), + })?; let billing = item.router_data.get_billing()?.to_owned(); diff --git a/crates/router/src/connector/braintree/braintree_graphql_transformers.rs b/crates/router/src/connector/braintree/braintree_graphql_transformers.rs index 190cd276572..78c4ee0e100 100644 --- a/crates/router/src/connector/braintree/braintree_graphql_transformers.rs +++ b/crates/router/src/connector/braintree/braintree_graphql_transformers.rs @@ -10,6 +10,7 @@ use crate::{ core::errors, services, types::{self, api, storage::enums}, + unimplemented_payment_method, }; pub const CLIENT_TOKEN_MUTATION: &str = "mutation createClientToken($input: CreateClientTokenInput!) { createClientToken(input: $input) { clientToken}}"; @@ -1334,9 +1335,9 @@ impl input: PaymentInput { payment_method_id: match item.router_data.get_payment_method_token()? { types::PaymentMethodToken::Token(token) => token.into(), - types::PaymentMethodToken::ApplePayDecrypt(_) => { - Err(errors::ConnectorError::InvalidWalletToken)? - } + types::PaymentMethodToken::ApplePayDecrypt(_) => Err( + unimplemented_payment_method!("Apple Pay", "Simplified", "Braintree"), + )?, }, transaction: TransactionBody { amount: item.amount.to_owned(), @@ -1416,9 +1417,11 @@ fn get_braintree_redirect_form( .expose(), card_token: match payment_method_token { types::PaymentMethodToken::Token(token) => token, - types::PaymentMethodToken::ApplePayDecrypt(_) => { - Err(errors::ConnectorError::InvalidWalletToken)? - } + types::PaymentMethodToken::ApplePayDecrypt(_) => Err(unimplemented_payment_method!( + "Apple Pay", + "Simplified", + "Braintree" + ))?, }, bin: match card_details { api_models::payments::PaymentMethodData::Card(card_details) => { diff --git a/crates/router/src/connector/checkout/transformers.rs b/crates/router/src/connector/checkout/transformers.rs index 64fddca13b5..6328f98081d 100644 --- a/crates/router/src/connector/checkout/transformers.rs +++ b/crates/router/src/connector/checkout/transformers.rs @@ -14,6 +14,7 @@ use crate::{ core::errors, services, types::{self, api, storage::enums, transformers::ForeignFrom}, + unimplemented_payment_method, }; #[derive(Debug, Serialize)] @@ -92,12 +93,12 @@ impl TryFrom<&types::TokenizationRouterData> for TokenRequest { api::PaymentMethodData::Wallet(wallet_data) => match wallet_data.clone() { api_models::payments::WalletData::GooglePay(_data) => { let json_wallet_data: CheckoutGooglePayData = - wallet_data.get_wallet_token_as_json()?; + wallet_data.get_wallet_token_as_json("Google Pay".to_string())?; Ok(Self::Googlepay(json_wallet_data)) } api_models::payments::WalletData::ApplePay(_data) => { let json_wallet_data: CheckoutApplePayData = - wallet_data.get_wallet_token_as_json()?; + wallet_data.get_wallet_token_as_json("Apple Pay".to_string())?; Ok(Self::Applepay(json_wallet_data)) } api_models::payments::WalletData::AliPayQr(_) @@ -308,7 +309,11 @@ impl TryFrom<&CheckoutRouterData<&types::PaymentsAuthorizeRouterData>> for Payme token: match item.router_data.get_payment_method_token()? { types::PaymentMethodToken::Token(token) => token.into(), types::PaymentMethodToken::ApplePayDecrypt(_) => { - Err(errors::ConnectorError::InvalidWalletToken)? + Err(unimplemented_payment_method!( + "Apple Pay", + "Simplified", + "Checkout" + ))? } }, })) diff --git a/crates/router/src/connector/cybersource/transformers.rs b/crates/router/src/connector/cybersource/transformers.rs index d9fab9a9025..19d5e177226 100644 --- a/crates/router/src/connector/cybersource/transformers.rs +++ b/crates/router/src/connector/cybersource/transformers.rs @@ -23,6 +23,7 @@ use crate::{ transformers::ForeignFrom, ApplePayPredecryptData, }, + unimplemented_payment_method, }; #[derive(Debug, Serialize)] @@ -139,9 +140,9 @@ impl TryFrom<&types::SetupMandateRouterData> for CybersourceZeroMandateRequest { Some(PaymentSolution::ApplePay), ) } - types::PaymentMethodToken::Token(_) => { - Err(errors::ConnectorError::InvalidWalletToken)? - } + types::PaymentMethodToken::Token(_) => Err( + unimplemented_payment_method!("Apple Pay", "Manual", "Cybersource"), + )?, }, None => ( PaymentInformation::ApplePayToken(ApplePayTokenPaymentInformation { @@ -980,7 +981,11 @@ impl TryFrom<&CybersourceRouterData<&types::PaymentsAuthorizeRouterData>> Self::try_from((item, decrypt_data, apple_pay_data)) } types::PaymentMethodToken::Token(_) => { - Err(errors::ConnectorError::InvalidWalletToken)? + Err(unimplemented_payment_method!( + "Apple Pay", + "Manual", + "Cybersource" + ))? } }, None => { diff --git a/crates/router/src/connector/globalpay/transformers.rs b/crates/router/src/connector/globalpay/transformers.rs index 1e410946251..35987ae26b3 100644 --- a/crates/router/src/connector/globalpay/transformers.rs +++ b/crates/router/src/connector/globalpay/transformers.rs @@ -459,7 +459,7 @@ fn get_wallet_data( api_models::payments::WalletData::GooglePay(_) => { Ok(PaymentMethodData::DigitalWallet(requests::DigitalWallet { provider: Some(requests::DigitalWalletProvider::PayByGoogle), - payment_token: wallet_data.get_wallet_token_as_json()?, + payment_token: wallet_data.get_wallet_token_as_json("Google Pay".to_string())?, })) } _ => Err(errors::ConnectorError::NotImplemented( diff --git a/crates/router/src/connector/mollie/transformers.rs b/crates/router/src/connector/mollie/transformers.rs index 4c18b59cd14..be0c0475fd7 100644 --- a/crates/router/src/connector/mollie/transformers.rs +++ b/crates/router/src/connector/mollie/transformers.rs @@ -15,6 +15,7 @@ use crate::{ core::errors, services, types, types::storage::enums as storage_enums, + unimplemented_payment_method, }; type Error = error_stack::Report; @@ -178,7 +179,11 @@ impl TryFrom<&MollieRouterData<&types::PaymentsAuthorizeRouterData>> for MollieP card_token: Some(Secret::new(match pm_token { types::PaymentMethodToken::Token(token) => token, types::PaymentMethodToken::ApplePayDecrypt(_) => { - Err(errors::ConnectorError::InvalidWalletToken)? + Err(unimplemented_payment_method!( + "Apple Pay", + "Simplified", + "Mollie" + ))? } })), }, diff --git a/crates/router/src/connector/nexinets/transformers.rs b/crates/router/src/connector/nexinets/transformers.rs index 9fdaaa36b36..dc871891145 100644 --- a/crates/router/src/connector/nexinets/transformers.rs +++ b/crates/router/src/connector/nexinets/transformers.rs @@ -665,7 +665,7 @@ fn get_applepay_details( wallet_data: &api_models::payments::WalletData, applepay_data: &api_models::payments::ApplePayWalletData, ) -> CustomResult { - let payment_data = wallet_data.get_wallet_token_as_json()?; + let payment_data = wallet_data.get_wallet_token_as_json("Apple Pay".to_string())?; Ok(ApplePayDetails { payment_data, payment_method: ApplepayPaymentMethod { diff --git a/crates/router/src/connector/noon/transformers.rs b/crates/router/src/connector/noon/transformers.rs index 08cde4041d6..92def17aeae 100644 --- a/crates/router/src/connector/noon/transformers.rs +++ b/crates/router/src/connector/noon/transformers.rs @@ -259,7 +259,8 @@ impl TryFrom<&types::PaymentsAuthorizeRouterData> for NoonPaymentsRequest { api_models::payments::WalletData::ApplePay(apple_pay_data) => { let payment_token_data = NoonApplePayTokenData { token: NoonApplePayData { - payment_data: wallet_data.get_wallet_token_as_json()?, + payment_data: wallet_data + .get_wallet_token_as_json("Apple Pay".to_string())?, payment_method: NoonApplePayPaymentMethod { display_name: apple_pay_data.payment_method.display_name, network: apple_pay_data.payment_method.network, diff --git a/crates/router/src/connector/payme/transformers.rs b/crates/router/src/connector/payme/transformers.rs index 5a84d7c4ed8..4db0a0bd07b 100644 --- a/crates/router/src/connector/payme/transformers.rs +++ b/crates/router/src/connector/payme/transformers.rs @@ -21,6 +21,7 @@ use crate::{ core::errors, services, types::{self, api, storage::enums, MandateReference}, + unimplemented_payment_method, }; const LANGUAGE: &str = "en"; @@ -708,9 +709,9 @@ impl TryFrom<&types::PaymentsCompleteAuthorizeRouterData> for Pay3dsRequest { let pm_token = item.get_payment_method_token()?; let buyer_key = match pm_token { types::PaymentMethodToken::Token(token) => token, - types::PaymentMethodToken::ApplePayDecrypt(_) => { - Err(errors::ConnectorError::InvalidWalletToken)? - } + types::PaymentMethodToken::ApplePayDecrypt(_) => Err( + unimplemented_payment_method!("Apple Pay", "Simplified", "Payme"), + )?, }; Ok(Self { buyer_email, diff --git a/crates/router/src/connector/square/transformers.rs b/crates/router/src/connector/square/transformers.rs index 03bd0ac83ee..66a0282f923 100644 --- a/crates/router/src/connector/square/transformers.rs +++ b/crates/router/src/connector/square/transformers.rs @@ -10,6 +10,7 @@ use crate::{ self, api, storage::{self, enums}, }, + unimplemented_payment_method, }; impl TryFrom<(&types::TokenizationRouterData, BankDebitData)> for SquareTokenRequest { @@ -257,9 +258,9 @@ impl TryFrom<&types::PaymentsAuthorizeRouterData> for SquarePaymentsRequest { idempotency_key: Secret::new(item.attempt_id.clone()), source_id: Secret::new(match pm_token { types::PaymentMethodToken::Token(token) => token, - types::PaymentMethodToken::ApplePayDecrypt(_) => { - Err(errors::ConnectorError::InvalidWalletToken)? - } + types::PaymentMethodToken::ApplePayDecrypt(_) => Err( + unimplemented_payment_method!("Apple Pay", "Simplified", "Square"), + )?, }), amount_money: SquarePaymentsAmountData { amount: item.request.amount, diff --git a/crates/router/src/connector/stax/transformers.rs b/crates/router/src/connector/stax/transformers.rs index a9bb68d558e..d28b5c1fa46 100644 --- a/crates/router/src/connector/stax/transformers.rs +++ b/crates/router/src/connector/stax/transformers.rs @@ -9,6 +9,7 @@ use crate::{ }, core::errors, types::{self, api, storage::enums}, + unimplemented_payment_method, }; #[derive(Debug, Serialize)] @@ -80,9 +81,9 @@ impl TryFrom<&StaxRouterData<&types::PaymentsAuthorizeRouterData>> for StaxPayme pre_auth, payment_method_id: Secret::new(match pm_token { types::PaymentMethodToken::Token(token) => token, - types::PaymentMethodToken::ApplePayDecrypt(_) => { - Err(errors::ConnectorError::InvalidWalletToken)? - } + types::PaymentMethodToken::ApplePayDecrypt(_) => Err( + unimplemented_payment_method!("Apple Pay", "Simplified", "Stax"), + )?, }), idempotency_id: Some(item.router_data.connector_request_reference_id.clone()), }) @@ -99,9 +100,9 @@ impl TryFrom<&StaxRouterData<&types::PaymentsAuthorizeRouterData>> for StaxPayme pre_auth, payment_method_id: Secret::new(match pm_token { types::PaymentMethodToken::Token(token) => token, - types::PaymentMethodToken::ApplePayDecrypt(_) => { - Err(errors::ConnectorError::InvalidWalletToken)? - } + types::PaymentMethodToken::ApplePayDecrypt(_) => Err( + unimplemented_payment_method!("Apple Pay", "Simplified", "Stax"), + )?, }), idempotency_id: Some(item.router_data.connector_request_reference_id.clone()), }) diff --git a/crates/router/src/connector/stripe/transformers.rs b/crates/router/src/connector/stripe/transformers.rs index a4c1668816c..860065b2b03 100644 --- a/crates/router/src/connector/stripe/transformers.rs +++ b/crates/router/src/connector/stripe/transformers.rs @@ -29,6 +29,7 @@ use crate::{ storage::enums, transformers::{ForeignFrom, ForeignTryFrom}, }, + unimplemented_payment_method, utils::OptionExt, }; @@ -1541,9 +1542,7 @@ impl TryFrom<(&payments::WalletData, Option)> if apple_pay_decrypt_data.is_none() { apple_pay_decrypt_data = Some(Self::Wallet(StripeWallet::ApplepayToken(StripeApplePay { - pk_token: applepay_data - .get_applepay_decoded_payment_data() - .change_context(errors::ConnectorError::RequestEncodingFailed)?, + pk_token: applepay_data.get_applepay_decoded_payment_data()?, pk_token_instrument_name: applepay_data .payment_method .pm_type @@ -1715,7 +1714,9 @@ impl TryFrom<&payments::GooglePayWalletData> for StripePaymentMethodData { .token .as_bytes() .parse_struct::("StripeGpayToken") - .change_context(errors::ConnectorError::RequestEncodingFailed)? + .change_context(errors::ConnectorError::InvalidWalletToken { + wallet_name: "Google Pay".to_string(), + })? .id, ), payment_type: StripePaymentMethodType::Card, @@ -1862,12 +1863,15 @@ impl TryFrom<&types::PaymentsAuthorizeRouterData> for PaymentIntentRequest { .payment_method_token .to_owned() .get_required_value("payment_token") - .change_context(errors::ConnectorError::RequestEncodingFailed)?; + .change_context(errors::ConnectorError::InvalidWalletToken { + wallet_name: "Apple Pay".to_string(), + })?; + let payment_method_token = match payment_method_token { types::PaymentMethodToken::Token(payment_method_token) => payment_method_token, - types::PaymentMethodToken::ApplePayDecrypt(_) => { - Err(errors::ConnectorError::InvalidWalletToken)? - } + types::PaymentMethodToken::ApplePayDecrypt(_) => Err( + unimplemented_payment_method!("Apple Pay", "Simplified", "Stripe"), + )?, }; Some(StripePaymentMethodData::Wallet( StripeWallet::ApplepayPayment(ApplepayPayment { diff --git a/crates/router/src/connector/utils.rs b/crates/router/src/connector/utils.rs index e510f3bfafc..a41c05f19be 100644 --- a/crates/router/src/connector/utils.rs +++ b/crates/router/src/connector/utils.rs @@ -900,7 +900,7 @@ fn get_card_issuer(card_number: &str) -> Result { } pub trait WalletData { fn get_wallet_token(&self) -> Result, Error>; - fn get_wallet_token_as_json(&self) -> Result + fn get_wallet_token_as_json(&self, wallet_name: String) -> Result where T: serde::de::DeserializeOwned; fn get_encoded_wallet_token(&self) -> Result; @@ -915,26 +915,31 @@ impl WalletData for api::WalletData { _ => Err(errors::ConnectorError::InvalidWallet.into()), } } - fn get_wallet_token_as_json(&self) -> Result + fn get_wallet_token_as_json(&self, wallet_name: String) -> Result where T: serde::de::DeserializeOwned, { serde_json::from_str::(self.get_wallet_token()?.peek()) .into_report() - .change_context(errors::ConnectorError::InvalidWalletToken) + .change_context(errors::ConnectorError::InvalidWalletToken { wallet_name }) } fn get_encoded_wallet_token(&self) -> Result { match self { Self::GooglePay(_) => { - let json_token: serde_json::Value = self.get_wallet_token_as_json()?; + let json_token: serde_json::Value = + self.get_wallet_token_as_json("Google Pay".to_owned())?; let token_as_vec = serde_json::to_vec(&json_token) .into_report() - .change_context(errors::ConnectorError::InvalidWalletToken)?; + .change_context(errors::ConnectorError::InvalidWalletToken { + wallet_name: "Google Pay".to_string(), + })?; let encoded_token = consts::BASE64_ENGINE.encode(token_as_vec); Ok(encoded_token) } - _ => Err(errors::ConnectorError::InvalidWalletToken.into()), + _ => Err( + errors::ConnectorError::NotImplemented("SELECTED PAYMENT METHOD".to_owned()).into(), + ), } } } @@ -950,10 +955,14 @@ impl ApplePay for payments::ApplePayWalletData { consts::BASE64_ENGINE .decode(&self.payment_data) .into_report() - .change_context(errors::ConnectorError::InvalidWalletToken)?, + .change_context(errors::ConnectorError::InvalidWalletToken { + wallet_name: "Apple Pay".to_string(), + })?, ) .into_report() - .change_context(errors::ConnectorError::InvalidWalletToken)?, + .change_context(errors::ConnectorError::InvalidWalletToken { + wallet_name: "Apple Pay".to_string(), + })?, ); Ok(token) } diff --git a/crates/router/src/connector/zen/transformers.rs b/crates/router/src/connector/zen/transformers.rs index b01b3f027a0..3e527423578 100644 --- a/crates/router/src/connector/zen/transformers.rs +++ b/crates/router/src/connector/zen/transformers.rs @@ -473,13 +473,17 @@ impl ZenPaymentChannels::PclApplepay, session .apple_pay - .ok_or(errors::ConnectorError::RequestEncodingFailed)?, + .ok_or(errors::ConnectorError::InvalidWalletToken { + wallet_name: "Apple Pay".to_string(), + })?, ), api_models::payments::WalletData::GooglePayRedirect(_) => ( ZenPaymentChannels::PclGooglepay, session .google_pay - .ok_or(errors::ConnectorError::RequestEncodingFailed)?, + .ok_or(errors::ConnectorError::InvalidWalletToken { + wallet_name: "Google Pay".to_string(), + })?, ), api_models::payments::WalletData::WeChatPayRedirect(_) | api_models::payments::WalletData::PaypalRedirect(_) diff --git a/crates/router/src/core/errors.rs b/crates/router/src/core/errors.rs index c468fea54c0..a7d36ff5128 100644 --- a/crates/router/src/core/errors.rs +++ b/crates/router/src/core/errors.rs @@ -68,6 +68,22 @@ macro_rules! capture_method_not_supported { }; } +#[macro_export] +macro_rules! unimplemented_payment_method { + ($payment_method:expr, $connector:expr) => { + errors::ConnectorError::NotImplemented(format!( + "{} through {}", + $payment_method, $connector + )) + }; + ($payment_method:expr, $flow:expr, $connector:expr) => { + errors::ConnectorError::NotImplemented(format!( + "{} {} through {}", + $payment_method, $flow, $connector + )) + }; +} + macro_rules! impl_error_type { ($name: ident, $arg: tt) => { #[derive(Debug)] @@ -179,8 +195,8 @@ pub enum ConnectorError { InvalidDataFormat { field_name: &'static str }, #[error("Payment Method data / Payment Method Type / Payment Experience Mismatch ")] MismatchedPaymentData, - #[error("Failed to parse Wallet token")] - InvalidWalletToken, + #[error("Failed to parse {wallet_name} wallet token")] + InvalidWalletToken { wallet_name: String }, #[error("Missing Connector Related Transaction ID")] MissingConnectorRelatedTransactionID { id: String }, #[error("File Validation failed")] diff --git a/crates/router/src/core/errors/api_error_response.rs b/crates/router/src/core/errors/api_error_response.rs index 3fc93e4e737..b3fbbaaf141 100644 --- a/crates/router/src/core/errors/api_error_response.rs +++ b/crates/router/src/core/errors/api_error_response.rs @@ -96,6 +96,11 @@ pub enum ApiErrorResponse { FileProviderNotSupported { message: String }, #[error(error_type = ErrorType::InvalidRequestError, code = "IR_23", message = "{message}")] UnprocessableEntity { message: String }, + #[error( + error_type = ErrorType::ProcessingError, code = "IR_24", + message = "Invalid {wallet_name} wallet token" + )] + InvalidWalletToken { wallet_name: String }, #[error(error_type = ErrorType::ConnectorError, code = "CE_00", message = "{code}: {message}", ignore = "status_code")] ExternalConnectorError { code: String, @@ -122,7 +127,6 @@ pub enum ApiErrorResponse { VerificationFailed { data: Option }, #[error(error_type = ErrorType::ProcessingError, code = "CE_08", message = "Dispute operation failed while processing with connector. Retry operation")] DisputeFailed { data: Option }, - #[error(error_type = ErrorType::ServerNotAvailable, code = "HE_00", message = "Something went wrong")] InternalServerError, #[error(error_type = ErrorType::LockTimeout, code = "HE_00", message = "Resource is busy. Please try again later.")] diff --git a/crates/router/src/core/errors/transformers.rs b/crates/router/src/core/errors/transformers.rs index b570dda4375..110feb22df3 100644 --- a/crates/router/src/core/errors/transformers.rs +++ b/crates/router/src/core/errors/transformers.rs @@ -96,6 +96,11 @@ impl ErrorSwitch for ApiErrorRespon AER::BadRequest(ApiError::new("IR", 23, message.to_string(), None)) }, Self::UnprocessableEntity {message} => AER::Unprocessable(ApiError::new("IR", 23, message.to_string(), None)), + Self::InvalidWalletToken { wallet_name} => AER::Unprocessable(ApiError::new( + "IR", + 24, + format!("Invalid {wallet_name} wallet token"), None + )), Self::ExternalConnectorError { code, message, diff --git a/crates/router/src/core/errors/utils.rs b/crates/router/src/core/errors/utils.rs index d9b4e190137..f664c33681c 100644 --- a/crates/router/src/core/errors/utils.rs +++ b/crates/router/src/core/errors/utils.rs @@ -204,7 +204,7 @@ impl ConnectorErrorExt for error_stack::Result | errors::ConnectorError::DateFormattingFailed | errors::ConnectorError::InvalidDataFormat { .. } | errors::ConnectorError::MismatchedPaymentData - | errors::ConnectorError::InvalidWalletToken + | errors::ConnectorError::InvalidWalletToken { .. } | errors::ConnectorError::MissingConnectorRelatedTransactionID { .. } | errors::ConnectorError::FileValidationFailed { .. } | errors::ConnectorError::MissingConnectorRedirectionPayload { .. } @@ -265,6 +265,7 @@ impl ConnectorErrorExt for error_stack::Result errors::ConnectorError::InvalidDataFormat { field_name } => { errors::ApiErrorResponse::InvalidDataValue { field_name } }, + errors::ConnectorError::InvalidWalletToken {wallet_name} => errors::ApiErrorResponse::InvalidWalletToken {wallet_name: wallet_name.to_string()}, errors::ConnectorError::CurrencyNotSupported { message, connector} => errors::ApiErrorResponse::CurrencyNotSupported { message: format!("Credentials for the currency {message} are not configured with the connector {connector}/hyperswitch") }, errors::ConnectorError::FailedToObtainAuthType => errors::ApiErrorResponse::InvalidConnectorConfiguration {config: "connector_account_details".to_string()}, errors::ConnectorError::InvalidConnectorConfig { config } => errors::ApiErrorResponse::InvalidConnectorConfiguration { config: config.to_string() }, @@ -299,7 +300,6 @@ impl ConnectorErrorExt for error_stack::Result errors::ConnectorError::WebhookResponseEncodingFailed | errors::ConnectorError::InvalidDateFormat | errors::ConnectorError::DateFormattingFailed | - errors::ConnectorError::InvalidWalletToken | errors::ConnectorError::MissingConnectorRelatedTransactionID { .. } | errors::ConnectorError::FileValidationFailed { .. } | errors::ConnectorError::MissingConnectorRedirectionPayload { .. } | @@ -347,6 +347,11 @@ impl ConnectorErrorExt for error_stack::Result config: field_name.to_string(), } } + errors::ConnectorError::InvalidWalletToken { wallet_name } => { + errors::ApiErrorResponse::InvalidWalletToken { + wallet_name: wallet_name.to_string(), + } + } errors::ConnectorError::RequestEncodingFailed | errors::ConnectorError::RequestEncodingFailedWithReason(_) | errors::ConnectorError::ParsingFailed @@ -384,7 +389,6 @@ impl ConnectorErrorExt for error_stack::Result | errors::ConnectorError::DateFormattingFailed | errors::ConnectorError::InvalidDataFormat { .. } | errors::ConnectorError::MismatchedPaymentData - | errors::ConnectorError::InvalidWalletToken | errors::ConnectorError::MissingConnectorRelatedTransactionID { .. } | errors::ConnectorError::FileValidationFailed { .. } | errors::ConnectorError::MissingConnectorRedirectionPayload { .. } diff --git a/crates/router/src/core/payments/helpers.rs b/crates/router/src/core/payments/helpers.rs index 112e3e64d6d..7eab4c0d26a 100644 --- a/crates/router/src/core/payments/helpers.rs +++ b/crates/router/src/core/payments/helpers.rs @@ -3605,8 +3605,10 @@ impl ApplePayData { pub fn token_json( wallet_data: api_models::payments::WalletData, ) -> CustomResult { - let json_wallet_data: Self = - connector::utils::WalletData::get_wallet_token_as_json(&wallet_data)?; + let json_wallet_data: Self = connector::utils::WalletData::get_wallet_token_as_json( + &wallet_data, + "Apple Pay".to_string(), + )?; Ok(json_wallet_data) } diff --git a/crates/storage_impl/src/errors.rs b/crates/storage_impl/src/errors.rs index 59ddacc5dc4..7002d0946f7 100644 --- a/crates/storage_impl/src/errors.rs +++ b/crates/storage_impl/src/errors.rs @@ -374,7 +374,7 @@ pub enum ConnectorError { #[error("Payment Method data / Payment Method Type / Payment Experience Mismatch ")] MismatchedPaymentData, #[error("Failed to parse Wallet token")] - InvalidWalletToken, + InvalidWalletToken { wallet_name: String }, #[error("Missing Connector Related Transaction ID")] MissingConnectorRelatedTransactionID { id: String }, #[error("File Validation failed")] From 37be05d31d97651ddaa2c67b828d24563b35d37e Mon Sep 17 00:00:00 2001 From: SamraatBansal <55536657+SamraatBansal@users.noreply.github.com> Date: Wed, 27 Mar 2024 13:37:49 +0530 Subject: [PATCH 07/20] feat(connector): [billwerk] add connector template code (#4123) Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com> --- config/config.example.toml | 1 + config/development.toml | 2 + config/docker_compose.toml | 2 + crates/api_models/src/enums.rs | 3 + crates/common_enums/src/enums.rs | 1 + crates/connector_configs/src/connector.rs | 2 + crates/router/src/configs/settings.rs | 1 + crates/router/src/connector.rs | 23 +- crates/router/src/connector/billwerk.rs | 561 ++++++++++++++++++ .../src/connector/billwerk/transformers.rs | 244 ++++++++ crates/router/src/core/admin.rs | 4 + crates/router/src/core/payments/flows.rs | 82 ++- crates/router/src/types/api.rs | 1 + crates/router/src/types/transformers.rs | 1 + crates/router/tests/connectors/billwerk.rs | 421 +++++++++++++ crates/router/tests/connectors/main.rs | 2 + .../router/tests/connectors/sample_auth.toml | 4 + crates/test_utils/src/connector_auth.rs | 1 + loadtest/config/development.toml | 2 + scripts/add_connector.sh | 2 +- 20 files changed, 1321 insertions(+), 39 deletions(-) create mode 100644 crates/router/src/connector/billwerk.rs create mode 100644 crates/router/src/connector/billwerk/transformers.rs create mode 100644 crates/router/tests/connectors/billwerk.rs diff --git a/config/config.example.toml b/config/config.example.toml index 81cd78f7244..ee868beb092 100644 --- a/config/config.example.toml +++ b/config/config.example.toml @@ -170,6 +170,7 @@ applepay.base_url = "https://apple-pay-gateway.apple.com/" authorizedotnet.base_url = "https://apitest.authorize.net/xml/v1/request.api" bambora.base_url = "https://api.na.bambora.com" bankofamerica.base_url = "https://apitest.merchant-services.bankofamerica.com/" +billwerk.base_url = "https://api.reepay.com/" bitpay.base_url = "https://test.bitpay.com" bluesnap.base_url = "https://sandbox.bluesnap.com/" bluesnap.secondary_base_url = "https://sandpay.bluesnap.com/" diff --git a/config/development.toml b/config/development.toml index 66ed76c8f3c..8d18e63122f 100644 --- a/config/development.toml +++ b/config/development.toml @@ -97,6 +97,7 @@ cards = [ "authorizedotnet", "bambora", "bankofamerica", + "billwerk", "bitpay", "bluesnap", "boku", @@ -165,6 +166,7 @@ applepay.base_url = "https://apple-pay-gateway.apple.com/" authorizedotnet.base_url = "https://apitest.authorize.net/xml/v1/request.api" bambora.base_url = "https://api.na.bambora.com" bankofamerica.base_url = "https://apitest.merchant-services.bankofamerica.com/" +billwerk.base_url = "https://api.reepay.com/" bitpay.base_url = "https://test.bitpay.com" bluesnap.base_url = "https://sandbox.bluesnap.com/" bluesnap.secondary_base_url = "https://sandpay.bluesnap.com/" diff --git a/config/docker_compose.toml b/config/docker_compose.toml index 7677fc4582d..ceb00ff212e 100644 --- a/config/docker_compose.toml +++ b/config/docker_compose.toml @@ -104,6 +104,7 @@ applepay.base_url = "https://apple-pay-gateway.apple.com/" authorizedotnet.base_url = "https://apitest.authorize.net/xml/v1/request.api" bambora.base_url = "https://api.na.bambora.com" bankofamerica.base_url = "https://apitest.merchant-services.bankofamerica.com/" +billwerk.base_url = "https://api.reepay.com/" bitpay.base_url = "https://test.bitpay.com" bluesnap.base_url = "https://sandbox.bluesnap.com/" bluesnap.secondary_base_url = "https://sandpay.bluesnap.com/" @@ -176,6 +177,7 @@ cards = [ "authorizedotnet", "bambora", "bankofamerica", + "billwerk", "bitpay", "bluesnap", "boku", diff --git a/crates/api_models/src/enums.rs b/crates/api_models/src/enums.rs index f712871abe1..b29377886d5 100644 --- a/crates/api_models/src/enums.rs +++ b/crates/api_models/src/enums.rs @@ -78,6 +78,7 @@ pub enum Connector { Authorizedotnet, Bambora, Bankofamerica, + // Billwerk, Added as template code for future usage Bitpay, Bluesnap, Boku, @@ -165,6 +166,7 @@ impl Connector { | Self::Authorizedotnet | Self::Bambora | Self::Bankofamerica + // | Self::Billwerk Added as template code for future usage | Self::Bitpay | Self::Bluesnap | Self::Boku @@ -221,6 +223,7 @@ impl Connector { | Self::Authorizedotnet | Self::Bambora | Self::Bankofamerica + // | Self::Billwerk Added as template for future usage | Self::Bitpay | Self::Bluesnap | Self::Boku diff --git a/crates/common_enums/src/enums.rs b/crates/common_enums/src/enums.rs index 89ca80e72b3..65842a4203d 100644 --- a/crates/common_enums/src/enums.rs +++ b/crates/common_enums/src/enums.rs @@ -115,6 +115,7 @@ pub enum RoutableConnectors { Airwallex, Authorizedotnet, Bankofamerica, + // Billwerk, Added as template code for future usage Bitpay, Bambora, Bluesnap, diff --git a/crates/connector_configs/src/connector.rs b/crates/connector_configs/src/connector.rs index 2ef80f8f2f6..74317319f50 100644 --- a/crates/connector_configs/src/connector.rs +++ b/crates/connector_configs/src/connector.rs @@ -116,6 +116,7 @@ pub struct ConnectorConfig { pub airwallex: Option, pub authorizedotnet: Option, pub bankofamerica: Option, + pub billwerk: Option, pub bitpay: Option, pub bluesnap: Option, pub boku: Option, @@ -227,6 +228,7 @@ impl ConnectorConfig { Connector::Airwallex => Ok(connector_data.airwallex), Connector::Authorizedotnet => Ok(connector_data.authorizedotnet), Connector::Bankofamerica => Ok(connector_data.bankofamerica), + // Connector::Billwerk => Ok(connector_data.billwerk), Added as template code for future usage Connector::Bitpay => Ok(connector_data.bitpay), Connector::Bluesnap => Ok(connector_data.bluesnap), Connector::Boku => Ok(connector_data.boku), diff --git a/crates/router/src/configs/settings.rs b/crates/router/src/configs/settings.rs index 2f87c5c21d7..d92812cee40 100644 --- a/crates/router/src/configs/settings.rs +++ b/crates/router/src/configs/settings.rs @@ -480,6 +480,7 @@ pub struct Connectors { pub authorizedotnet: ConnectorParams, pub bambora: ConnectorParams, pub bankofamerica: ConnectorParams, + pub billwerk: ConnectorParams, pub bitpay: ConnectorParams, pub bluesnap: ConnectorParamsWithSecondaryBaseUrl, pub boku: ConnectorParams, diff --git a/crates/router/src/connector.rs b/crates/router/src/connector.rs index eccdf3f9ddf..d786ed4e31b 100644 --- a/crates/router/src/connector.rs +++ b/crates/router/src/connector.rs @@ -4,6 +4,7 @@ pub mod airwallex; pub mod authorizedotnet; pub mod bambora; pub mod bankofamerica; +pub mod billwerk; pub mod bitpay; pub mod bluesnap; pub mod boku; @@ -60,15 +61,15 @@ pub mod zen; pub use self::dummyconnector::DummyConnector; pub use self::{ aci::Aci, adyen::Adyen, airwallex::Airwallex, authorizedotnet::Authorizedotnet, - bambora::Bambora, bankofamerica::Bankofamerica, bitpay::Bitpay, bluesnap::Bluesnap, boku::Boku, - braintree::Braintree, cashtocode::Cashtocode, checkout::Checkout, coinbase::Coinbase, - cryptopay::Cryptopay, cybersource::Cybersource, dlocal::Dlocal, fiserv::Fiserv, forte::Forte, - globalpay::Globalpay, globepay::Globepay, gocardless::Gocardless, helcim::Helcim, - iatapay::Iatapay, klarna::Klarna, mollie::Mollie, multisafepay::Multisafepay, - nexinets::Nexinets, nmi::Nmi, noon::Noon, nuvei::Nuvei, opayo::Opayo, opennode::Opennode, - payeezy::Payeezy, payme::Payme, paypal::Paypal, payu::Payu, placetopay::Placetopay, - powertranz::Powertranz, prophetpay::Prophetpay, rapyd::Rapyd, riskified::Riskified, - shift4::Shift4, signifyd::Signifyd, square::Square, stax::Stax, stripe::Stripe, - threedsecureio::Threedsecureio, trustpay::Trustpay, tsys::Tsys, volt::Volt, wise::Wise, - worldline::Worldline, worldpay::Worldpay, zen::Zen, + bambora::Bambora, bankofamerica::Bankofamerica, billwerk::Billwerk, bitpay::Bitpay, + bluesnap::Bluesnap, boku::Boku, braintree::Braintree, cashtocode::Cashtocode, + checkout::Checkout, coinbase::Coinbase, cryptopay::Cryptopay, cybersource::Cybersource, + dlocal::Dlocal, fiserv::Fiserv, forte::Forte, globalpay::Globalpay, globepay::Globepay, + gocardless::Gocardless, helcim::Helcim, iatapay::Iatapay, klarna::Klarna, mollie::Mollie, + multisafepay::Multisafepay, nexinets::Nexinets, nmi::Nmi, noon::Noon, nuvei::Nuvei, + opayo::Opayo, opennode::Opennode, payeezy::Payeezy, payme::Payme, paypal::Paypal, payu::Payu, + placetopay::Placetopay, powertranz::Powertranz, prophetpay::Prophetpay, rapyd::Rapyd, + riskified::Riskified, shift4::Shift4, signifyd::Signifyd, square::Square, stax::Stax, + stripe::Stripe, threedsecureio::Threedsecureio, trustpay::Trustpay, tsys::Tsys, volt::Volt, + wise::Wise, worldline::Worldline, worldpay::Worldpay, zen::Zen, }; diff --git a/crates/router/src/connector/billwerk.rs b/crates/router/src/connector/billwerk.rs new file mode 100644 index 00000000000..c7d81e06c32 --- /dev/null +++ b/crates/router/src/connector/billwerk.rs @@ -0,0 +1,561 @@ +pub mod transformers; + +use std::fmt::Debug; + +use error_stack::{IntoReport, ResultExt}; +use masking::ExposeInterface; +use transformers as billwerk; + +use crate::{ + configs::settings, + core::errors::{self, CustomResult}, + events::connector_api_logs::ConnectorEvent, + headers, + services::{ + self, + request::{self, Mask}, + ConnectorIntegration, ConnectorValidation, + }, + types::{ + self, + api::{self, ConnectorCommon, ConnectorCommonExt}, + ErrorResponse, RequestContent, Response, + }, + utils::BytesExt, +}; + +#[derive(Debug, Clone)] +pub struct Billwerk; + +impl api::Payment for Billwerk {} +impl api::PaymentSession for Billwerk {} +impl api::ConnectorAccessToken for Billwerk {} +impl api::MandateSetup for Billwerk {} +impl api::PaymentAuthorize for Billwerk {} +impl api::PaymentSync for Billwerk {} +impl api::PaymentCapture for Billwerk {} +impl api::PaymentVoid for Billwerk {} +impl api::Refund for Billwerk {} +impl api::RefundExecute for Billwerk {} +impl api::RefundSync for Billwerk {} +impl api::PaymentToken for Billwerk {} + +impl + ConnectorIntegration< + api::PaymentMethodToken, + types::PaymentMethodTokenizationData, + types::PaymentsResponseData, + > for Billwerk +{ + // Not Implemented (R) +} + +impl ConnectorCommonExt for Billwerk +where + Self: ConnectorIntegration, +{ + fn build_headers( + &self, + req: &types::RouterData, + _connectors: &settings::Connectors, + ) -> CustomResult)>, errors::ConnectorError> { + let mut header = vec![( + headers::CONTENT_TYPE.to_string(), + self.get_content_type().to_string().into(), + )]; + let mut api_key = self.get_auth_header(&req.connector_auth_type)?; + header.append(&mut api_key); + Ok(header) + } +} + +impl ConnectorCommon for Billwerk { + fn id(&self) -> &'static str { + "billwerk" + } + + fn get_currency_unit(&self) -> api::CurrencyUnit { + api::CurrencyUnit::Minor + } + + fn common_get_content_type(&self) -> &'static str { + "application/json" + } + + fn base_url<'a>(&self, connectors: &'a settings::Connectors) -> &'a str { + connectors.billwerk.base_url.as_ref() + } + + fn get_auth_header( + &self, + auth_type: &types::ConnectorAuthType, + ) -> CustomResult)>, errors::ConnectorError> { + let auth = billwerk::BillwerkAuthType::try_from(auth_type) + .change_context(errors::ConnectorError::FailedToObtainAuthType)?; + Ok(vec![( + headers::AUTHORIZATION.to_string(), + auth.api_key.expose().into_masked(), + )]) + } + + fn build_error_response( + &self, + res: Response, + event_builder: Option<&mut ConnectorEvent>, + ) -> CustomResult { + let response: billwerk::BillwerkErrorResponse = res + .response + .parse_struct("BillwerkErrorResponse") + .change_context(errors::ConnectorError::ResponseDeserializationFailed)?; + + event_builder.map(|i| i.set_response_body(&response)); + router_env::logger::info!(connector_response=?response); + + Ok(ErrorResponse { + status_code: res.status_code, + code: response.code, + message: response.message, + reason: response.reason, + attempt_status: None, + connector_transaction_id: None, + }) + } +} + +impl ConnectorValidation for Billwerk { + //TODO: implement functions when support enabled +} + +impl ConnectorIntegration + for Billwerk +{ + //TODO: implement sessions flow +} + +impl ConnectorIntegration + for Billwerk +{ +} + +impl + ConnectorIntegration< + api::SetupMandate, + types::SetupMandateRequestData, + types::PaymentsResponseData, + > for Billwerk +{ +} + +impl ConnectorIntegration + for Billwerk +{ + fn get_headers( + &self, + req: &types::PaymentsAuthorizeRouterData, + connectors: &settings::Connectors, + ) -> CustomResult)>, errors::ConnectorError> { + self.build_headers(req, connectors) + } + + fn get_content_type(&self) -> &'static str { + self.common_get_content_type() + } + + fn get_url( + &self, + _req: &types::PaymentsAuthorizeRouterData, + _connectors: &settings::Connectors, + ) -> CustomResult { + Err(errors::ConnectorError::NotImplemented("get_url method".to_string()).into()) + } + + fn get_request_body( + &self, + req: &types::PaymentsAuthorizeRouterData, + _connectors: &settings::Connectors, + ) -> CustomResult { + let connector_router_data = billwerk::BillwerkRouterData::try_from(( + &self.get_currency_unit(), + req.request.currency, + req.request.amount, + req, + ))?; + let connector_req = billwerk::BillwerkPaymentsRequest::try_from(&connector_router_data)?; + Ok(RequestContent::Json(Box::new(connector_req))) + } + + fn build_request( + &self, + req: &types::PaymentsAuthorizeRouterData, + connectors: &settings::Connectors, + ) -> CustomResult, errors::ConnectorError> { + Ok(Some( + services::RequestBuilder::new() + .method(services::Method::Post) + .url(&types::PaymentsAuthorizeType::get_url( + self, req, connectors, + )?) + .attach_default_headers() + .headers(types::PaymentsAuthorizeType::get_headers( + self, req, connectors, + )?) + .set_body(types::PaymentsAuthorizeType::get_request_body( + self, req, connectors, + )?) + .build(), + )) + } + + fn handle_response( + &self, + data: &types::PaymentsAuthorizeRouterData, + event_builder: Option<&mut ConnectorEvent>, + res: Response, + ) -> CustomResult { + let response: billwerk::BillwerkPaymentsResponse = res + .response + .parse_struct("Billwerk PaymentsAuthorizeResponse") + .change_context(errors::ConnectorError::ResponseDeserializationFailed)?; + event_builder.map(|i| i.set_response_body(&response)); + router_env::logger::info!(connector_response=?response); + types::RouterData::try_from(types::ResponseRouterData { + response, + data: data.clone(), + http_code: res.status_code, + }) + } + + fn get_error_response( + &self, + res: Response, + event_builder: Option<&mut ConnectorEvent>, + ) -> CustomResult { + self.build_error_response(res, event_builder) + } +} + +impl ConnectorIntegration + for Billwerk +{ + fn get_headers( + &self, + req: &types::PaymentsSyncRouterData, + connectors: &settings::Connectors, + ) -> CustomResult)>, errors::ConnectorError> { + self.build_headers(req, connectors) + } + + fn get_content_type(&self) -> &'static str { + self.common_get_content_type() + } + + fn get_url( + &self, + _req: &types::PaymentsSyncRouterData, + _connectors: &settings::Connectors, + ) -> CustomResult { + Err(errors::ConnectorError::NotImplemented("get_url method".to_string()).into()) + } + + fn build_request( + &self, + req: &types::PaymentsSyncRouterData, + connectors: &settings::Connectors, + ) -> CustomResult, errors::ConnectorError> { + Ok(Some( + services::RequestBuilder::new() + .method(services::Method::Get) + .url(&types::PaymentsSyncType::get_url(self, req, connectors)?) + .attach_default_headers() + .headers(types::PaymentsSyncType::get_headers(self, req, connectors)?) + .build(), + )) + } + + fn handle_response( + &self, + data: &types::PaymentsSyncRouterData, + event_builder: Option<&mut ConnectorEvent>, + res: Response, + ) -> CustomResult { + let response: billwerk::BillwerkPaymentsResponse = res + .response + .parse_struct("billwerk PaymentsSyncResponse") + .change_context(errors::ConnectorError::ResponseDeserializationFailed)?; + event_builder.map(|i| i.set_response_body(&response)); + router_env::logger::info!(connector_response=?response); + types::RouterData::try_from(types::ResponseRouterData { + response, + data: data.clone(), + http_code: res.status_code, + }) + } + + fn get_error_response( + &self, + res: Response, + event_builder: Option<&mut ConnectorEvent>, + ) -> CustomResult { + self.build_error_response(res, event_builder) + } +} + +impl ConnectorIntegration + for Billwerk +{ + fn get_headers( + &self, + req: &types::PaymentsCaptureRouterData, + connectors: &settings::Connectors, + ) -> CustomResult)>, errors::ConnectorError> { + self.build_headers(req, connectors) + } + + fn get_content_type(&self) -> &'static str { + self.common_get_content_type() + } + + fn get_url( + &self, + _req: &types::PaymentsCaptureRouterData, + _connectors: &settings::Connectors, + ) -> CustomResult { + Err(errors::ConnectorError::NotImplemented("get_url method".to_string()).into()) + } + + fn get_request_body( + &self, + _req: &types::PaymentsCaptureRouterData, + _connectors: &settings::Connectors, + ) -> CustomResult { + Err(errors::ConnectorError::NotImplemented("get_request_body method".to_string()).into()) + } + + fn build_request( + &self, + req: &types::PaymentsCaptureRouterData, + connectors: &settings::Connectors, + ) -> CustomResult, errors::ConnectorError> { + Ok(Some( + services::RequestBuilder::new() + .method(services::Method::Post) + .url(&types::PaymentsCaptureType::get_url(self, req, connectors)?) + .attach_default_headers() + .headers(types::PaymentsCaptureType::get_headers( + self, req, connectors, + )?) + .set_body(types::PaymentsCaptureType::get_request_body( + self, req, connectors, + )?) + .build(), + )) + } + + fn handle_response( + &self, + data: &types::PaymentsCaptureRouterData, + event_builder: Option<&mut ConnectorEvent>, + res: Response, + ) -> CustomResult { + let response: billwerk::BillwerkPaymentsResponse = res + .response + .parse_struct("Billwerk PaymentsCaptureResponse") + .change_context(errors::ConnectorError::ResponseDeserializationFailed)?; + event_builder.map(|i| i.set_response_body(&response)); + router_env::logger::info!(connector_response=?response); + types::RouterData::try_from(types::ResponseRouterData { + response, + data: data.clone(), + http_code: res.status_code, + }) + } + + fn get_error_response( + &self, + res: Response, + event_builder: Option<&mut ConnectorEvent>, + ) -> CustomResult { + self.build_error_response(res, event_builder) + } +} + +impl ConnectorIntegration + for Billwerk +{ +} + +impl ConnectorIntegration + for Billwerk +{ + fn get_headers( + &self, + req: &types::RefundsRouterData, + connectors: &settings::Connectors, + ) -> CustomResult)>, errors::ConnectorError> { + self.build_headers(req, connectors) + } + + fn get_content_type(&self) -> &'static str { + self.common_get_content_type() + } + + fn get_url( + &self, + _req: &types::RefundsRouterData, + _connectors: &settings::Connectors, + ) -> CustomResult { + Err(errors::ConnectorError::NotImplemented("get_url method".to_string()).into()) + } + + fn get_request_body( + &self, + req: &types::RefundsRouterData, + _connectors: &settings::Connectors, + ) -> CustomResult { + let connector_router_data = billwerk::BillwerkRouterData::try_from(( + &self.get_currency_unit(), + req.request.currency, + req.request.refund_amount, + req, + ))?; + let connector_req = billwerk::BillwerkRefundRequest::try_from(&connector_router_data)?; + Ok(RequestContent::Json(Box::new(connector_req))) + } + + fn build_request( + &self, + req: &types::RefundsRouterData, + connectors: &settings::Connectors, + ) -> CustomResult, errors::ConnectorError> { + let request = services::RequestBuilder::new() + .method(services::Method::Post) + .url(&types::RefundExecuteType::get_url(self, req, connectors)?) + .attach_default_headers() + .headers(types::RefundExecuteType::get_headers( + self, req, connectors, + )?) + .set_body(types::RefundExecuteType::get_request_body( + self, req, connectors, + )?) + .build(); + Ok(Some(request)) + } + + fn handle_response( + &self, + data: &types::RefundsRouterData, + event_builder: Option<&mut ConnectorEvent>, + res: Response, + ) -> CustomResult, errors::ConnectorError> { + let response: billwerk::RefundResponse = res + .response + .parse_struct("billwerk RefundResponse") + .change_context(errors::ConnectorError::ResponseDeserializationFailed)?; + event_builder.map(|i| i.set_response_body(&response)); + router_env::logger::info!(connector_response=?response); + types::RouterData::try_from(types::ResponseRouterData { + response, + data: data.clone(), + http_code: res.status_code, + }) + } + + fn get_error_response( + &self, + res: Response, + event_builder: Option<&mut ConnectorEvent>, + ) -> CustomResult { + self.build_error_response(res, event_builder) + } +} + +impl ConnectorIntegration for Billwerk { + fn get_headers( + &self, + req: &types::RefundSyncRouterData, + connectors: &settings::Connectors, + ) -> CustomResult)>, errors::ConnectorError> { + self.build_headers(req, connectors) + } + + fn get_content_type(&self) -> &'static str { + self.common_get_content_type() + } + + fn get_url( + &self, + _req: &types::RefundSyncRouterData, + _connectors: &settings::Connectors, + ) -> CustomResult { + Err(errors::ConnectorError::NotImplemented("get_url method".to_string()).into()) + } + + fn build_request( + &self, + req: &types::RefundSyncRouterData, + connectors: &settings::Connectors, + ) -> CustomResult, errors::ConnectorError> { + Ok(Some( + services::RequestBuilder::new() + .method(services::Method::Get) + .url(&types::RefundSyncType::get_url(self, req, connectors)?) + .attach_default_headers() + .headers(types::RefundSyncType::get_headers(self, req, connectors)?) + .set_body(types::RefundSyncType::get_request_body( + self, req, connectors, + )?) + .build(), + )) + } + + fn handle_response( + &self, + data: &types::RefundSyncRouterData, + event_builder: Option<&mut ConnectorEvent>, + res: Response, + ) -> CustomResult { + let response: billwerk::RefundResponse = res + .response + .parse_struct("billwerk RefundSyncResponse") + .change_context(errors::ConnectorError::ResponseDeserializationFailed)?; + event_builder.map(|i| i.set_response_body(&response)); + router_env::logger::info!(connector_response=?response); + types::RouterData::try_from(types::ResponseRouterData { + response, + data: data.clone(), + http_code: res.status_code, + }) + } + + fn get_error_response( + &self, + res: Response, + event_builder: Option<&mut ConnectorEvent>, + ) -> CustomResult { + self.build_error_response(res, event_builder) + } +} + +#[async_trait::async_trait] +impl api::IncomingWebhook for Billwerk { + fn get_webhook_object_reference_id( + &self, + _request: &api::IncomingWebhookRequestDetails<'_>, + ) -> CustomResult { + Err(errors::ConnectorError::WebhooksNotImplemented).into_report() + } + + fn get_webhook_event_type( + &self, + _request: &api::IncomingWebhookRequestDetails<'_>, + ) -> CustomResult { + Err(errors::ConnectorError::WebhooksNotImplemented).into_report() + } + + fn get_webhook_resource_object( + &self, + _request: &api::IncomingWebhookRequestDetails<'_>, + ) -> CustomResult, errors::ConnectorError> { + Err(errors::ConnectorError::WebhooksNotImplemented).into_report() + } +} diff --git a/crates/router/src/connector/billwerk/transformers.rs b/crates/router/src/connector/billwerk/transformers.rs new file mode 100644 index 00000000000..c6f025b7898 --- /dev/null +++ b/crates/router/src/connector/billwerk/transformers.rs @@ -0,0 +1,244 @@ +use masking::Secret; +use serde::{Deserialize, Serialize}; + +use crate::{ + connector::utils::PaymentsAuthorizeRequestData, + core::errors, + types::{self, api, storage::enums}, +}; + +//TODO: Fill the struct with respective fields +pub struct BillwerkRouterData { + pub amount: i64, // The type of amount that a connector accepts, for example, String, i64, f64, etc. + pub router_data: T, +} + +impl + TryFrom<( + &types::api::CurrencyUnit, + types::storage::enums::Currency, + i64, + T, + )> for BillwerkRouterData +{ + type Error = error_stack::Report; + fn try_from( + (_currency_unit, _currency, amount, item): ( + &types::api::CurrencyUnit, + types::storage::enums::Currency, + i64, + T, + ), + ) -> Result { + //Todo : use utils to convert the amount to the type of amount that a connector accepts + Ok(Self { + amount, + router_data: item, + }) + } +} + +//TODO: Fill the struct with respective fields +#[derive(Default, Debug, Serialize, Eq, PartialEq)] +pub struct BillwerkPaymentsRequest { + amount: i64, + card: BillwerkCard, +} + +#[derive(Default, Debug, Serialize, Eq, PartialEq)] +pub struct BillwerkCard { + number: cards::CardNumber, + expiry_month: Secret, + expiry_year: Secret, + cvc: Secret, + complete: bool, +} + +impl TryFrom<&BillwerkRouterData<&types::PaymentsAuthorizeRouterData>> for BillwerkPaymentsRequest { + type Error = error_stack::Report; + fn try_from( + item: &BillwerkRouterData<&types::PaymentsAuthorizeRouterData>, + ) -> Result { + match item.router_data.request.payment_method_data.clone() { + api::PaymentMethodData::Card(req_card) => { + let card = BillwerkCard { + number: req_card.card_number, + expiry_month: req_card.card_exp_month, + expiry_year: req_card.card_exp_year, + cvc: req_card.card_cvc, + complete: item.router_data.request.is_auto_capture()?, + }; + Ok(Self { + amount: item.amount.to_owned(), + card, + }) + } + _ => Err(errors::ConnectorError::NotImplemented("Payment methods".to_string()).into()), + } + } +} + +//TODO: Fill the struct with respective fields +// Auth Struct +pub struct BillwerkAuthType { + pub(super) api_key: Secret, +} + +impl TryFrom<&types::ConnectorAuthType> for BillwerkAuthType { + type Error = error_stack::Report; + fn try_from(auth_type: &types::ConnectorAuthType) -> Result { + match auth_type { + types::ConnectorAuthType::HeaderKey { api_key } => Ok(Self { + api_key: api_key.to_owned(), + }), + _ => Err(errors::ConnectorError::FailedToObtainAuthType.into()), + } + } +} +// PaymentsResponse +//TODO: Append the remaining status flags +#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq)] +#[serde(rename_all = "lowercase")] +pub enum BillwerkPaymentStatus { + Succeeded, + Failed, + #[default] + Processing, +} + +impl From for enums::AttemptStatus { + fn from(item: BillwerkPaymentStatus) -> Self { + match item { + BillwerkPaymentStatus::Succeeded => Self::Charged, + BillwerkPaymentStatus::Failed => Self::Failure, + BillwerkPaymentStatus::Processing => Self::Authorizing, + } + } +} + +//TODO: Fill the struct with respective fields +#[derive(Default, Debug, Clone, Serialize, Deserialize, PartialEq)] +pub struct BillwerkPaymentsResponse { + status: BillwerkPaymentStatus, + id: String, +} + +impl + TryFrom> + for types::RouterData +{ + type Error = error_stack::Report; + fn try_from( + item: types::ResponseRouterData< + F, + BillwerkPaymentsResponse, + T, + types::PaymentsResponseData, + >, + ) -> Result { + Ok(Self { + status: enums::AttemptStatus::from(item.response.status), + response: Ok(types::PaymentsResponseData::TransactionResponse { + resource_id: types::ResponseId::ConnectorTransactionId(item.response.id), + redirection_data: None, + mandate_reference: None, + connector_metadata: None, + network_txn_id: None, + connector_response_reference_id: None, + incremental_authorization_allowed: None, + }), + ..item.data + }) + } +} + +//TODO: Fill the struct with respective fields +// REFUND : +// Type definition for RefundRequest +#[derive(Default, Debug, Serialize)] +pub struct BillwerkRefundRequest { + pub amount: i64, +} + +impl TryFrom<&BillwerkRouterData<&types::RefundsRouterData>> for BillwerkRefundRequest { + type Error = error_stack::Report; + fn try_from( + item: &BillwerkRouterData<&types::RefundsRouterData>, + ) -> Result { + Ok(Self { + amount: item.amount.to_owned(), + }) + } +} + +// Type definition for Refund Response + +#[allow(dead_code)] +#[derive(Debug, Serialize, Default, Deserialize, Clone)] +pub enum RefundStatus { + Succeeded, + Failed, + #[default] + Processing, +} + +impl From for enums::RefundStatus { + fn from(item: RefundStatus) -> Self { + match item { + RefundStatus::Succeeded => Self::Success, + RefundStatus::Failed => Self::Failure, + RefundStatus::Processing => Self::Pending, + //TODO: Review mapping + } + } +} + +//TODO: Fill the struct with respective fields +#[derive(Default, Debug, Clone, Serialize, Deserialize)] +pub struct RefundResponse { + id: String, + status: RefundStatus, +} + +impl TryFrom> + for types::RefundsRouterData +{ + type Error = error_stack::Report; + fn try_from( + item: types::RefundsResponseRouterData, + ) -> Result { + Ok(Self { + response: Ok(types::RefundsResponseData { + connector_refund_id: item.response.id.to_string(), + refund_status: enums::RefundStatus::from(item.response.status), + }), + ..item.data + }) + } +} + +impl TryFrom> + for types::RefundsRouterData +{ + type Error = error_stack::Report; + fn try_from( + item: types::RefundsResponseRouterData, + ) -> Result { + Ok(Self { + response: Ok(types::RefundsResponseData { + connector_refund_id: item.response.id.to_string(), + refund_status: enums::RefundStatus::from(item.response.status), + }), + ..item.data + }) + } +} + +//TODO: Fill the struct with respective fields +#[derive(Default, Debug, Serialize, Deserialize, PartialEq)] +pub struct BillwerkErrorResponse { + pub status_code: u16, + pub code: String, + pub message: String, + pub reason: Option, +} diff --git a/crates/router/src/core/admin.rs b/crates/router/src/core/admin.rs index 2f546cfa5ac..a4be66242ee 100644 --- a/crates/router/src/core/admin.rs +++ b/crates/router/src/core/admin.rs @@ -1739,6 +1739,10 @@ pub(crate) fn validate_auth_and_metadata_type( bankofamerica::transformers::BankOfAmericaAuthType::try_from(val)?; Ok(()) } + // api_enums::Connector::Billwerk => { + // billwerk::transformers::BillwerkAuthType::try_from(val)?; + // Ok(()) + // } Added as template code for future usage api_enums::Connector::Bitpay => { bitpay::transformers::BitpayAuthType::try_from(val)?; Ok(()) diff --git a/crates/router/src/core/payments/flows.rs b/crates/router/src/core/payments/flows.rs index fe4a504861d..6c952dc2593 100644 --- a/crates/router/src/core/payments/flows.rs +++ b/crates/router/src/core/payments/flows.rs @@ -145,9 +145,9 @@ impl } default_imp_for_complete_authorize!( - connector::Threedsecureio, connector::Aci, connector::Adyen, + connector::Billwerk, connector::Bitpay, connector::Boku, connector::Cashtocode, @@ -176,6 +176,7 @@ default_imp_for_complete_authorize!( connector::Square, connector::Stax, connector::Stripe, + connector::Threedsecureio, connector::Trustpay, connector::Tsys, connector::Volt, @@ -211,13 +212,13 @@ impl { } default_imp_for_webhook_source_verification!( - connector::Threedsecureio, connector::Aci, connector::Adyen, connector::Airwallex, connector::Authorizedotnet, connector::Bambora, connector::Bankofamerica, + connector::Billwerk, connector::Bitpay, connector::Bluesnap, connector::Braintree, @@ -257,6 +258,7 @@ default_imp_for_webhook_source_verification!( connector::Square, connector::Stax, connector::Stripe, + connector::Threedsecureio, connector::Trustpay, connector::Tsys, connector::Volt, @@ -294,13 +296,13 @@ impl } default_imp_for_create_customer!( - connector::Threedsecureio, connector::Aci, connector::Adyen, connector::Airwallex, connector::Authorizedotnet, connector::Bambora, connector::Bankofamerica, + connector::Billwerk, connector::Bitpay, connector::Bluesnap, connector::Boku, @@ -338,6 +340,7 @@ default_imp_for_create_customer!( connector::Shift4, connector::Signifyd, connector::Square, + connector::Threedsecureio, connector::Trustpay, connector::Tsys, connector::Volt, @@ -377,11 +380,11 @@ impl services::ConnectorRedirectResponse for connector::DummyConnec } default_imp_for_connector_redirect_response!( - connector::Threedsecureio, connector::Aci, connector::Adyen, connector::Bitpay, connector::Bankofamerica, + connector::Billwerk, connector::Boku, connector::Cashtocode, connector::Coinbase, @@ -410,6 +413,7 @@ default_imp_for_connector_redirect_response!( connector::Signifyd, connector::Square, connector::Stax, + connector::Threedsecureio, connector::Tsys, connector::Volt, connector::Wise, @@ -429,13 +433,13 @@ macro_rules! default_imp_for_connector_request_id { impl api::ConnectorTransactionId for connector::DummyConnector {} default_imp_for_connector_request_id!( - connector::Threedsecureio, connector::Aci, connector::Adyen, connector::Airwallex, connector::Authorizedotnet, connector::Bambora, connector::Bankofamerica, + connector::Billwerk, connector::Bitpay, connector::Bluesnap, connector::Boku, @@ -474,6 +478,7 @@ default_imp_for_connector_request_id!( connector::Square, connector::Stax, connector::Stripe, + connector::Threedsecureio, connector::Trustpay, connector::Tsys, connector::Volt, @@ -514,13 +519,13 @@ impl } default_imp_for_accept_dispute!( - connector::Threedsecureio, connector::Aci, connector::Adyen, connector::Airwallex, connector::Authorizedotnet, connector::Bambora, connector::Bankofamerica, + connector::Billwerk, connector::Bitpay, connector::Bluesnap, connector::Boku, @@ -560,6 +565,7 @@ default_imp_for_accept_dispute!( connector::Square, connector::Stax, connector::Stripe, + connector::Threedsecureio, connector::Trustpay, connector::Tsys, connector::Volt, @@ -619,13 +625,13 @@ impl } default_imp_for_file_upload!( - connector::Threedsecureio, connector::Aci, connector::Adyen, connector::Airwallex, connector::Authorizedotnet, connector::Bambora, connector::Bankofamerica, + connector::Billwerk, connector::Bitpay, connector::Bluesnap, connector::Boku, @@ -663,6 +669,7 @@ default_imp_for_file_upload!( connector::Signifyd, connector::Square, connector::Stax, + connector::Threedsecureio, connector::Trustpay, connector::Tsys, connector::Volt, @@ -701,13 +708,13 @@ impl } default_imp_for_submit_evidence!( - connector::Threedsecureio, connector::Aci, connector::Adyen, connector::Airwallex, connector::Authorizedotnet, connector::Bambora, connector::Bankofamerica, + connector::Billwerk, connector::Bitpay, connector::Bluesnap, connector::Boku, @@ -745,6 +752,7 @@ default_imp_for_submit_evidence!( connector::Signifyd, connector::Square, connector::Stax, + connector::Threedsecureio, connector::Trustpay, connector::Tsys, connector::Volt, @@ -783,13 +791,13 @@ impl } default_imp_for_defend_dispute!( - connector::Threedsecureio, connector::Aci, connector::Adyen, connector::Airwallex, connector::Authorizedotnet, connector::Bambora, connector::Bankofamerica, + connector::Billwerk, connector::Bitpay, connector::Bluesnap, connector::Boku, @@ -828,6 +836,7 @@ default_imp_for_defend_dispute!( connector::Square, connector::Stax, connector::Stripe, + connector::Threedsecureio, connector::Trustpay, connector::Tsys, connector::Volt, @@ -866,11 +875,11 @@ impl } default_imp_for_pre_processing_steps!( - connector::Threedsecureio, connector::Aci, connector::Airwallex, connector::Authorizedotnet, connector::Bambora, + connector::Billwerk, connector::Bitpay, connector::Bluesnap, connector::Boku, @@ -905,6 +914,7 @@ default_imp_for_pre_processing_steps!( connector::Signifyd, connector::Square, connector::Stax, + connector::Threedsecureio, connector::Tsys, connector::Volt, connector::Wise, @@ -925,12 +935,12 @@ macro_rules! default_imp_for_payouts { impl api::Payouts for connector::DummyConnector {} default_imp_for_payouts!( - connector::Threedsecureio, connector::Aci, connector::Airwallex, connector::Authorizedotnet, connector::Bambora, connector::Bankofamerica, + connector::Billwerk, connector::Bitpay, connector::Bluesnap, connector::Boku, @@ -971,6 +981,7 @@ default_imp_for_payouts!( connector::Stax, connector::Stripe, connector::Shift4, + connector::Threedsecureio, connector::Trustpay, connector::Tsys, connector::Volt, @@ -1008,12 +1019,12 @@ impl #[cfg(feature = "payouts")] default_imp_for_payouts_create!( - connector::Threedsecureio, connector::Aci, connector::Airwallex, connector::Authorizedotnet, connector::Bambora, connector::Bankofamerica, + connector::Billwerk, connector::Bitpay, connector::Bluesnap, connector::Boku, @@ -1054,6 +1065,7 @@ default_imp_for_payouts_create!( connector::Stax, connector::Stripe, connector::Shift4, + connector::Threedsecureio, connector::Trustpay, connector::Tsys, connector::Volt, @@ -1094,12 +1106,12 @@ impl #[cfg(feature = "payouts")] default_imp_for_payouts_eligibility!( - connector::Threedsecureio, connector::Aci, connector::Airwallex, connector::Authorizedotnet, connector::Bambora, connector::Bankofamerica, + connector::Billwerk, connector::Bitpay, connector::Bluesnap, connector::Boku, @@ -1140,6 +1152,7 @@ default_imp_for_payouts_eligibility!( connector::Stax, connector::Stripe, connector::Shift4, + connector::Threedsecureio, connector::Trustpay, connector::Tsys, connector::Volt, @@ -1177,12 +1190,12 @@ impl #[cfg(feature = "payouts")] default_imp_for_payouts_fulfill!( - connector::Threedsecureio, connector::Aci, connector::Airwallex, connector::Authorizedotnet, connector::Bambora, connector::Bankofamerica, + connector::Billwerk, connector::Bitpay, connector::Bluesnap, connector::Boku, @@ -1223,6 +1236,7 @@ default_imp_for_payouts_fulfill!( connector::Stax, connector::Stripe, connector::Shift4, + connector::Threedsecureio, connector::Trustpay, connector::Tsys, connector::Volt, @@ -1260,12 +1274,12 @@ impl #[cfg(feature = "payouts")] default_imp_for_payouts_cancel!( - connector::Threedsecureio, connector::Aci, connector::Airwallex, connector::Authorizedotnet, connector::Bambora, connector::Bankofamerica, + connector::Billwerk, connector::Bitpay, connector::Bluesnap, connector::Boku, @@ -1306,6 +1320,7 @@ default_imp_for_payouts_cancel!( connector::Stax, connector::Stripe, connector::Shift4, + connector::Threedsecureio, connector::Trustpay, connector::Tsys, connector::Volt, @@ -1343,13 +1358,13 @@ impl #[cfg(feature = "payouts")] default_imp_for_payouts_quote!( - connector::Threedsecureio, connector::Aci, connector::Adyen, connector::Airwallex, connector::Authorizedotnet, connector::Bambora, connector::Bankofamerica, + connector::Billwerk, connector::Bitpay, connector::Bluesnap, connector::Boku, @@ -1390,6 +1405,7 @@ default_imp_for_payouts_quote!( connector::Stax, connector::Stripe, connector::Shift4, + connector::Threedsecureio, connector::Trustpay, connector::Tsys, connector::Volt, @@ -1427,13 +1443,13 @@ impl #[cfg(feature = "payouts")] default_imp_for_payouts_recipient!( - connector::Threedsecureio, connector::Aci, connector::Adyen, connector::Airwallex, connector::Authorizedotnet, connector::Bambora, connector::Bankofamerica, + connector::Billwerk, connector::Bitpay, connector::Bluesnap, connector::Boku, @@ -1474,6 +1490,7 @@ default_imp_for_payouts_recipient!( connector::Stax, connector::Stripe, connector::Shift4, + connector::Threedsecureio, connector::Trustpay, connector::Tsys, connector::Volt, @@ -1510,13 +1527,13 @@ impl } default_imp_for_approve!( - connector::Threedsecureio, connector::Aci, connector::Adyen, connector::Airwallex, connector::Authorizedotnet, connector::Bambora, connector::Bankofamerica, + connector::Billwerk, connector::Bitpay, connector::Bluesnap, connector::Boku, @@ -1557,6 +1574,7 @@ default_imp_for_approve!( connector::Stax, connector::Stripe, connector::Shift4, + connector::Threedsecureio, connector::Trustpay, connector::Tsys, connector::Volt, @@ -1594,13 +1612,13 @@ impl } default_imp_for_reject!( - connector::Threedsecureio, connector::Aci, connector::Adyen, connector::Airwallex, connector::Authorizedotnet, connector::Bambora, connector::Bankofamerica, + connector::Billwerk, connector::Bitpay, connector::Bluesnap, connector::Boku, @@ -1641,6 +1659,7 @@ default_imp_for_reject!( connector::Stax, connector::Stripe, connector::Shift4, + connector::Threedsecureio, connector::Trustpay, connector::Tsys, connector::Volt, @@ -1662,13 +1681,13 @@ macro_rules! default_imp_for_fraud_check { impl api::FraudCheck for connector::DummyConnector {} default_imp_for_fraud_check!( - connector::Threedsecureio, connector::Aci, connector::Adyen, connector::Airwallex, connector::Authorizedotnet, connector::Bambora, connector::Bankofamerica, + connector::Billwerk, connector::Bitpay, connector::Bluesnap, connector::Boku, @@ -1707,6 +1726,7 @@ default_imp_for_fraud_check!( connector::Stax, connector::Stripe, connector::Shift4, + connector::Threedsecureio, connector::Trustpay, connector::Tsys, connector::Volt, @@ -1746,13 +1766,13 @@ impl #[cfg(feature = "frm")] default_imp_for_frm_sale!( - connector::Threedsecureio, connector::Aci, connector::Adyen, connector::Airwallex, connector::Authorizedotnet, connector::Bambora, connector::Bankofamerica, + connector::Billwerk, connector::Bitpay, connector::Bluesnap, connector::Boku, @@ -1791,6 +1811,7 @@ default_imp_for_frm_sale!( connector::Stax, connector::Stripe, connector::Shift4, + connector::Threedsecureio, connector::Trustpay, connector::Tsys, connector::Volt, @@ -1830,13 +1851,13 @@ impl #[cfg(feature = "frm")] default_imp_for_frm_checkout!( - connector::Threedsecureio, connector::Aci, connector::Adyen, connector::Airwallex, connector::Authorizedotnet, connector::Bambora, connector::Bankofamerica, + connector::Billwerk, connector::Bitpay, connector::Bluesnap, connector::Boku, @@ -1875,6 +1896,7 @@ default_imp_for_frm_checkout!( connector::Stax, connector::Stripe, connector::Shift4, + connector::Threedsecureio, connector::Trustpay, connector::Tsys, connector::Volt, @@ -1914,13 +1936,13 @@ impl #[cfg(feature = "frm")] default_imp_for_frm_transaction!( - connector::Threedsecureio, connector::Aci, connector::Adyen, connector::Airwallex, connector::Authorizedotnet, connector::Bambora, connector::Bankofamerica, + connector::Billwerk, connector::Bitpay, connector::Bluesnap, connector::Boku, @@ -1959,6 +1981,7 @@ default_imp_for_frm_transaction!( connector::Stax, connector::Stripe, connector::Shift4, + connector::Threedsecureio, connector::Trustpay, connector::Tsys, connector::Volt, @@ -1998,13 +2021,13 @@ impl #[cfg(feature = "frm")] default_imp_for_frm_fulfillment!( - connector::Threedsecureio, connector::Aci, connector::Adyen, connector::Airwallex, connector::Authorizedotnet, connector::Bambora, connector::Bankofamerica, + connector::Billwerk, connector::Bitpay, connector::Bluesnap, connector::Boku, @@ -2043,6 +2066,7 @@ default_imp_for_frm_fulfillment!( connector::Stax, connector::Stripe, connector::Shift4, + connector::Threedsecureio, connector::Trustpay, connector::Tsys, connector::Volt, @@ -2082,13 +2106,13 @@ impl #[cfg(feature = "frm")] default_imp_for_frm_record_return!( - connector::Threedsecureio, connector::Aci, connector::Adyen, connector::Airwallex, connector::Authorizedotnet, connector::Bambora, connector::Bankofamerica, + connector::Billwerk, connector::Bitpay, connector::Bluesnap, connector::Boku, @@ -2127,6 +2151,7 @@ default_imp_for_frm_record_return!( connector::Stax, connector::Stripe, connector::Shift4, + connector::Threedsecureio, connector::Trustpay, connector::Tsys, connector::Volt, @@ -2164,13 +2189,13 @@ impl } default_imp_for_incremental_authorization!( - connector::Threedsecureio, connector::Aci, connector::Adyen, connector::Airwallex, connector::Authorizedotnet, connector::Bambora, connector::Bankofamerica, + connector::Billwerk, connector::Bitpay, connector::Bluesnap, connector::Boku, @@ -2210,6 +2235,7 @@ default_imp_for_incremental_authorization!( connector::Stax, connector::Stripe, connector::Shift4, + connector::Threedsecureio, connector::Trustpay, connector::Tsys, connector::Volt, @@ -2245,13 +2271,13 @@ impl { } default_imp_for_revoking_mandates!( - connector::Threedsecureio, connector::Aci, connector::Adyen, connector::Airwallex, connector::Authorizedotnet, connector::Bambora, connector::Bankofamerica, + connector::Billwerk, connector::Bitpay, connector::Bluesnap, connector::Boku, @@ -2290,6 +2316,7 @@ default_imp_for_revoking_mandates!( connector::Stax, connector::Stripe, connector::Shift4, + connector::Threedsecureio, connector::Trustpay, connector::Tsys, connector::Volt, @@ -2373,6 +2400,7 @@ default_imp_for_connector_authentication!( connector::Authorizedotnet, connector::Bambora, connector::Bankofamerica, + connector::Billwerk, connector::Bitpay, connector::Bluesnap, connector::Boku, diff --git a/crates/router/src/types/api.rs b/crates/router/src/types/api.rs index cd9eee46eec..95a0989ac2b 100644 --- a/crates/router/src/types/api.rs +++ b/crates/router/src/types/api.rs @@ -328,6 +328,7 @@ impl ConnectorData { enums::Connector::Authorizedotnet => Ok(Box::new(&connector::Authorizedotnet)), enums::Connector::Bambora => Ok(Box::new(&connector::Bambora)), enums::Connector::Bankofamerica => Ok(Box::new(&connector::Bankofamerica)), + // enums::Connector::Billwerk => Ok(Box::new(&connector::Billwerk)), Added as template code for future usage enums::Connector::Bitpay => Ok(Box::new(&connector::Bitpay)), enums::Connector::Bluesnap => Ok(Box::new(&connector::Bluesnap)), enums::Connector::Boku => Ok(Box::new(&connector::Boku)), diff --git a/crates/router/src/types/transformers.rs b/crates/router/src/types/transformers.rs index 29774be91af..2f0c9479914 100644 --- a/crates/router/src/types/transformers.rs +++ b/crates/router/src/types/transformers.rs @@ -188,6 +188,7 @@ impl ForeignTryFrom for common_enums::RoutableConnectors { api_enums::Connector::Authorizedotnet => Self::Authorizedotnet, api_enums::Connector::Bambora => Self::Bambora, api_enums::Connector::Bankofamerica => Self::Bankofamerica, + // api_enums::Connector::Billwerk => Self::Billwerk, Added as template code for future usage api_enums::Connector::Bitpay => Self::Bitpay, api_enums::Connector::Bluesnap => Self::Bluesnap, api_enums::Connector::Boku => Self::Boku, diff --git a/crates/router/tests/connectors/billwerk.rs b/crates/router/tests/connectors/billwerk.rs new file mode 100644 index 00000000000..1dec066e5d2 --- /dev/null +++ b/crates/router/tests/connectors/billwerk.rs @@ -0,0 +1,421 @@ +use masking::Secret; +use router::types::{self, api, storage::enums}; +use test_utils::connector_auth; + +use crate::utils::{self, ConnectorActions}; + +#[derive(Clone, Copy)] +struct BillwerkTest; +impl ConnectorActions for BillwerkTest {} +impl utils::Connector for BillwerkTest { + fn get_data(&self) -> types::api::ConnectorData { + use router::connector::Billwerk; + types::api::ConnectorData { + connector: Box::new(&Billwerk), + // Added as Dummy connector as template code is added for future usage + connector_name: types::Connector::DummyConnector1, + get_token: types::api::GetToken::Connector, + merchant_connector_id: None, + } + } + + fn get_auth_token(&self) -> types::ConnectorAuthType { + utils::to_connector_auth_type( + connector_auth::ConnectorAuthentication::new() + .billwerk + .expect("Missing connector authentication configuration") + .into(), + ) + } + + fn get_name(&self) -> String { + "billwerk".to_string() + } +} + +static CONNECTOR: BillwerkTest = BillwerkTest {}; + +fn get_default_payment_info() -> Option { + None +} + +fn payment_method_details() -> Option { + None +} + +// Cards Positive Tests +// Creates a payment using the manual capture flow (Non 3DS). +#[actix_web::test] +async fn should_only_authorize_payment() { + let response = CONNECTOR + .authorize_payment(payment_method_details(), get_default_payment_info()) + .await + .expect("Authorize payment response"); + assert_eq!(response.status, enums::AttemptStatus::Authorized); +} + +// Captures a payment using the manual capture flow (Non 3DS). +#[actix_web::test] +async fn should_capture_authorized_payment() { + let response = CONNECTOR + .authorize_and_capture_payment(payment_method_details(), None, get_default_payment_info()) + .await + .expect("Capture payment response"); + assert_eq!(response.status, enums::AttemptStatus::Charged); +} + +// Partially captures a payment using the manual capture flow (Non 3DS). +#[actix_web::test] +async fn should_partially_capture_authorized_payment() { + let response = CONNECTOR + .authorize_and_capture_payment( + payment_method_details(), + Some(types::PaymentsCaptureData { + amount_to_capture: 50, + ..utils::PaymentCaptureType::default().0 + }), + get_default_payment_info(), + ) + .await + .expect("Capture payment response"); + assert_eq!(response.status, enums::AttemptStatus::Charged); +} + +// Synchronizes a payment using the manual capture flow (Non 3DS). +#[actix_web::test] +async fn should_sync_authorized_payment() { + let authorize_response = CONNECTOR + .authorize_payment(payment_method_details(), get_default_payment_info()) + .await + .expect("Authorize payment response"); + let txn_id = utils::get_connector_transaction_id(authorize_response.response); + let response = CONNECTOR + .psync_retry_till_status_matches( + enums::AttemptStatus::Authorized, + Some(types::PaymentsSyncData { + connector_transaction_id: router::types::ResponseId::ConnectorTransactionId( + txn_id.unwrap(), + ), + ..Default::default() + }), + get_default_payment_info(), + ) + .await + .expect("PSync response"); + assert_eq!(response.status, enums::AttemptStatus::Authorized,); +} + +// Voids a payment using the manual capture flow (Non 3DS). +#[actix_web::test] +async fn should_void_authorized_payment() { + let response = CONNECTOR + .authorize_and_void_payment( + payment_method_details(), + Some(types::PaymentsCancelData { + connector_transaction_id: String::from(""), + cancellation_reason: Some("requested_by_customer".to_string()), + ..Default::default() + }), + get_default_payment_info(), + ) + .await + .expect("Void payment response"); + assert_eq!(response.status, enums::AttemptStatus::Voided); +} + +// Refunds a payment using the manual capture flow (Non 3DS). +#[actix_web::test] +async fn should_refund_manually_captured_payment() { + let response = CONNECTOR + .capture_payment_and_refund( + payment_method_details(), + None, + None, + get_default_payment_info(), + ) + .await + .unwrap(); + assert_eq!( + response.response.unwrap().refund_status, + enums::RefundStatus::Success, + ); +} + +// Partially refunds a payment using the manual capture flow (Non 3DS). +#[actix_web::test] +async fn should_partially_refund_manually_captured_payment() { + let response = CONNECTOR + .capture_payment_and_refund( + payment_method_details(), + None, + Some(types::RefundsData { + refund_amount: 50, + ..utils::PaymentRefundType::default().0 + }), + get_default_payment_info(), + ) + .await + .unwrap(); + assert_eq!( + response.response.unwrap().refund_status, + enums::RefundStatus::Success, + ); +} + +// Synchronizes a refund using the manual capture flow (Non 3DS). +#[actix_web::test] +async fn should_sync_manually_captured_refund() { + let refund_response = CONNECTOR + .capture_payment_and_refund( + payment_method_details(), + None, + None, + get_default_payment_info(), + ) + .await + .unwrap(); + let response = CONNECTOR + .rsync_retry_till_status_matches( + enums::RefundStatus::Success, + refund_response.response.unwrap().connector_refund_id, + None, + get_default_payment_info(), + ) + .await + .unwrap(); + assert_eq!( + response.response.unwrap().refund_status, + enums::RefundStatus::Success, + ); +} + +// Creates a payment using the automatic capture flow (Non 3DS). +#[actix_web::test] +async fn should_make_payment() { + let authorize_response = CONNECTOR + .make_payment(payment_method_details(), get_default_payment_info()) + .await + .unwrap(); + assert_eq!(authorize_response.status, enums::AttemptStatus::Charged); +} + +// Synchronizes a payment using the automatic capture flow (Non 3DS). +#[actix_web::test] +async fn should_sync_auto_captured_payment() { + let authorize_response = CONNECTOR + .make_payment(payment_method_details(), get_default_payment_info()) + .await + .unwrap(); + assert_eq!(authorize_response.status, enums::AttemptStatus::Charged); + let txn_id = utils::get_connector_transaction_id(authorize_response.response); + assert_ne!(txn_id, None, "Empty connector transaction id"); + let response = CONNECTOR + .psync_retry_till_status_matches( + enums::AttemptStatus::Charged, + Some(types::PaymentsSyncData { + connector_transaction_id: router::types::ResponseId::ConnectorTransactionId( + txn_id.unwrap(), + ), + capture_method: Some(enums::CaptureMethod::Automatic), + ..Default::default() + }), + get_default_payment_info(), + ) + .await + .unwrap(); + assert_eq!(response.status, enums::AttemptStatus::Charged,); +} + +// Refunds a payment using the automatic capture flow (Non 3DS). +#[actix_web::test] +async fn should_refund_auto_captured_payment() { + let response = CONNECTOR + .make_payment_and_refund(payment_method_details(), None, get_default_payment_info()) + .await + .unwrap(); + assert_eq!( + response.response.unwrap().refund_status, + enums::RefundStatus::Success, + ); +} + +// Partially refunds a payment using the automatic capture flow (Non 3DS). +#[actix_web::test] +async fn should_partially_refund_succeeded_payment() { + let refund_response = CONNECTOR + .make_payment_and_refund( + payment_method_details(), + Some(types::RefundsData { + refund_amount: 50, + ..utils::PaymentRefundType::default().0 + }), + get_default_payment_info(), + ) + .await + .unwrap(); + assert_eq!( + refund_response.response.unwrap().refund_status, + enums::RefundStatus::Success, + ); +} + +// Creates multiple refunds against a payment using the automatic capture flow (Non 3DS). +#[actix_web::test] +async fn should_refund_succeeded_payment_multiple_times() { + CONNECTOR + .make_payment_and_multiple_refund( + payment_method_details(), + Some(types::RefundsData { + refund_amount: 50, + ..utils::PaymentRefundType::default().0 + }), + get_default_payment_info(), + ) + .await; +} + +// Synchronizes a refund using the automatic capture flow (Non 3DS). +#[actix_web::test] +async fn should_sync_refund() { + let refund_response = CONNECTOR + .make_payment_and_refund(payment_method_details(), None, get_default_payment_info()) + .await + .unwrap(); + let response = CONNECTOR + .rsync_retry_till_status_matches( + enums::RefundStatus::Success, + refund_response.response.unwrap().connector_refund_id, + None, + get_default_payment_info(), + ) + .await + .unwrap(); + assert_eq!( + response.response.unwrap().refund_status, + enums::RefundStatus::Success, + ); +} + +// Cards Negative scenerios +// Creates a payment with incorrect CVC. +#[actix_web::test] +async fn should_fail_payment_for_incorrect_cvc() { + let response = CONNECTOR + .make_payment( + Some(types::PaymentsAuthorizeData { + payment_method_data: types::api::PaymentMethodData::Card(api::Card { + card_cvc: Secret::new("12345".to_string()), + ..utils::CCardType::default().0 + }), + ..utils::PaymentAuthorizeType::default().0 + }), + get_default_payment_info(), + ) + .await + .unwrap(); + assert_eq!( + response.response.unwrap_err().message, + "Your card's security code is invalid.".to_string(), + ); +} + +// Creates a payment with incorrect expiry month. +#[actix_web::test] +async fn should_fail_payment_for_invalid_exp_month() { + let response = CONNECTOR + .make_payment( + Some(types::PaymentsAuthorizeData { + payment_method_data: types::api::PaymentMethodData::Card(api::Card { + card_exp_month: Secret::new("20".to_string()), + ..utils::CCardType::default().0 + }), + ..utils::PaymentAuthorizeType::default().0 + }), + get_default_payment_info(), + ) + .await + .unwrap(); + assert_eq!( + response.response.unwrap_err().message, + "Your card's expiration month is invalid.".to_string(), + ); +} + +// Creates a payment with incorrect expiry year. +#[actix_web::test] +async fn should_fail_payment_for_incorrect_expiry_year() { + let response = CONNECTOR + .make_payment( + Some(types::PaymentsAuthorizeData { + payment_method_data: types::api::PaymentMethodData::Card(api::Card { + card_exp_year: Secret::new("2000".to_string()), + ..utils::CCardType::default().0 + }), + ..utils::PaymentAuthorizeType::default().0 + }), + get_default_payment_info(), + ) + .await + .unwrap(); + assert_eq!( + response.response.unwrap_err().message, + "Your card's expiration year is invalid.".to_string(), + ); +} + +// Voids a payment using automatic capture flow (Non 3DS). +#[actix_web::test] +async fn should_fail_void_payment_for_auto_capture() { + let authorize_response = CONNECTOR + .make_payment(payment_method_details(), get_default_payment_info()) + .await + .unwrap(); + assert_eq!(authorize_response.status, enums::AttemptStatus::Charged); + let txn_id = utils::get_connector_transaction_id(authorize_response.response); + assert_ne!(txn_id, None, "Empty connector transaction id"); + let void_response = CONNECTOR + .void_payment(txn_id.unwrap(), None, get_default_payment_info()) + .await + .unwrap(); + assert_eq!( + void_response.response.unwrap_err().message, + "You cannot cancel this PaymentIntent because it has a status of succeeded." + ); +} + +// Captures a payment using invalid connector payment id. +#[actix_web::test] +async fn should_fail_capture_for_invalid_payment() { + let capture_response = CONNECTOR + .capture_payment("123456789".to_string(), None, get_default_payment_info()) + .await + .unwrap(); + assert_eq!( + capture_response.response.unwrap_err().message, + String::from("No such payment_intent: '123456789'") + ); +} + +// Refunds a payment with refund amount higher than payment amount. +#[actix_web::test] +async fn should_fail_for_refund_amount_higher_than_payment_amount() { + let response = CONNECTOR + .make_payment_and_refund( + payment_method_details(), + Some(types::RefundsData { + refund_amount: 150, + ..utils::PaymentRefundType::default().0 + }), + get_default_payment_info(), + ) + .await + .unwrap(); + assert_eq!( + response.response.unwrap_err().message, + "Refund amount (₹1.50) is greater than charge amount (₹1.00)", + ); +} + +// Connector dependent test cases goes here + +// [#478]: add unit tests for non 3DS, wallets & webhooks in connector tests diff --git a/crates/router/tests/connectors/main.rs b/crates/router/tests/connectors/main.rs index 8db743d6098..eb428a36cb9 100644 --- a/crates/router/tests/connectors/main.rs +++ b/crates/router/tests/connectors/main.rs @@ -13,6 +13,8 @@ mod authorizedotnet; mod bambora; #[cfg(feature = "dummy_connector")] mod bankofamerica; +#[cfg(feature = "dummy_connector")] +mod billwerk; mod bitpay; mod bluesnap; mod boku; diff --git a/crates/router/tests/connectors/sample_auth.toml b/crates/router/tests/connectors/sample_auth.toml index 3f78ff7f491..bd17f279c2d 100644 --- a/crates/router/tests/connectors/sample_auth.toml +++ b/crates/router/tests/connectors/sample_auth.toml @@ -198,3 +198,7 @@ key1= "Trankey" [threedsecureio] api_key="API Key" + + +[billwerk] +api_key="API Key" diff --git a/crates/test_utils/src/connector_auth.rs b/crates/test_utils/src/connector_auth.rs index a2753a2c517..34a5e35928d 100644 --- a/crates/test_utils/src/connector_auth.rs +++ b/crates/test_utils/src/connector_auth.rs @@ -18,6 +18,7 @@ pub struct ConnectorAuthentication { pub authorizedotnet: Option, pub bambora: Option, pub bankofamerica: Option, + pub billwerk: Option, pub bitpay: Option, pub bluesnap: Option, pub boku: Option, diff --git a/loadtest/config/development.toml b/loadtest/config/development.toml index 6dfd921a251..9a9a7606ca1 100644 --- a/loadtest/config/development.toml +++ b/loadtest/config/development.toml @@ -71,6 +71,7 @@ applepay.base_url = "https://apple-pay-gateway.apple.com/" authorizedotnet.base_url = "https://apitest.authorize.net/xml/v1/request.api" bambora.base_url = "https://api.na.bambora.com" bankofamerica.base_url = "https://apitest.merchant-services.bankofamerica.com/" +billwerk.base_url = "https://api.reepay.com/" bitpay.base_url = "https://test.bitpay.com" bluesnap.base_url = "https://sandbox.bluesnap.com/" bluesnap.secondary_base_url = "https://sandpay.bluesnap.com/" @@ -142,6 +143,7 @@ cards = [ "authorizedotnet", "bambora", "bankofamerica", + "billwerk", "bitpay", "bluesnap", "boku", diff --git a/scripts/add_connector.sh b/scripts/add_connector.sh index 2be49d123b0..9098be40e21 100755 --- a/scripts/add_connector.sh +++ b/scripts/add_connector.sh @@ -6,7 +6,7 @@ function find_prev_connector() { git checkout $self cp $self $self.tmp # Add new connector to existing list and sort it - connectors=(aci adyen airwallex applepay authorizedotnet bambora bankofamerica bitpay bluesnap boku braintree cashtocode checkout coinbase cryptopay cybersource dlocal dummyconnector fiserv forte globalpay globepay gocardless helcim iatapay klarna mollie multisafepay nexinets noon nuvei opayo opennode payeezy payme paypal payu placetopay powertranz prophetpay rapyd shift4 square stax stripe threedsecureio trustpay tsys volt wise worldline worldpay "$1") + connectors=(aci adyen airwallex applepay authorizedotnet bambora bankofamerica billwerk bitpay bluesnap boku braintree cashtocode checkout coinbase cryptopay cybersource dlocal dummyconnector fiserv forte globalpay globepay gocardless helcim iatapay klarna mollie multisafepay nexinets noon nuvei opayo opennode payeezy payme paypal payu placetopay powertranz prophetpay rapyd shift4 square stax stripe threedsecureio trustpay tsys volt wise worldline worldpay "$1") IFS=$'\n' sorted=($(sort <<<"${connectors[*]}")); unset IFS res=`echo ${sorted[@]}` sed -i'' -e "s/^ connectors=.*/ connectors=($res \"\$1\")/" $self.tmp From 9798db4558d926a218a0ca6f7f7c4e24a187b3da Mon Sep 17 00:00:00 2001 From: Prasunna Soppa <70575890+prasunna09@users.noreply.github.com> Date: Wed, 27 Mar 2024 13:57:14 +0530 Subject: [PATCH 08/20] fix(trustpay): [Trustpay] Add error code mapping '800.100.100' (#4224) --- crates/router/src/connector/trustpay/transformers.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/router/src/connector/trustpay/transformers.rs b/crates/router/src/connector/trustpay/transformers.rs index 9d5d2e3d749..d898bd24896 100644 --- a/crates/router/src/connector/trustpay/transformers.rs +++ b/crates/router/src/connector/trustpay/transformers.rs @@ -491,6 +491,7 @@ fn is_payment_failed(payment_status: &str) -> (bool, &'static str) { ), "700.500.001" => (true, "Referenced session contains too many transactions"), "700.500.003" => (true, "Test accounts not allowed in production"), + "800.100.100" => (true, "Transaction declined for unknown reason"), "800.100.151" => (true, "Transaction declined (invalid card)"), "800.100.152" => (true, "Transaction declined by authorization system"), "800.100.153" => (true, "Transaction declined (invalid CVV)"), From 246898fbb00a67d5791827527ce45e01b01b232c Mon Sep 17 00:00:00 2001 From: Jeeva Ramachandran <120017870+JeevaRamu0104@users.noreply.github.com> Date: Wed, 27 Mar 2024 13:59:10 +0530 Subject: [PATCH 09/20] fix(euclid_wasm): checkout wasm metadata issue (#4198) Co-authored-by: Arjun Karthik --- crates/connector_configs/src/common_config.rs | 10 ++ .../src/response_modifier.rs | 121 +++++++----------- crates/connector_configs/src/transformer.rs | 16 +++ 3 files changed, 73 insertions(+), 74 deletions(-) diff --git a/crates/connector_configs/src/common_config.rs b/crates/connector_configs/src/common_config.rs index 2af5b88b337..495c0e5b6cc 100644 --- a/crates/connector_configs/src/common_config.rs +++ b/crates/connector_configs/src/common_config.rs @@ -82,6 +82,11 @@ pub struct ApiModelMetaData { pub apple_pay: Option, pub apple_pay_combined: Option, pub endpoint_prefix: Option, + pub mcc: Option, + pub merchant_country_code: Option, + pub merchant_name: Option, + pub acquirer_bin: Option, + pub acquirer_merchant_id: Option, } #[serde_with::skip_serializing_none] @@ -175,4 +180,9 @@ pub struct DashboardMetaData { pub apple_pay: Option, pub apple_pay_combined: Option, pub endpoint_prefix: Option, + pub mcc: Option, + pub merchant_country_code: Option, + pub merchant_name: Option, + pub acquirer_bin: Option, + pub acquirer_merchant_id: Option, } diff --git a/crates/connector_configs/src/response_modifier.rs b/crates/connector_configs/src/response_modifier.rs index 5942a9e01ae..6fbf85f4fcf 100644 --- a/crates/connector_configs/src/response_modifier.rs +++ b/crates/connector_configs/src/response_modifier.rs @@ -1,6 +1,7 @@ use crate::common_config::{ - CardProvider, ConnectorApiIntegrationPayload, DashboardMetaData, DashboardPaymentMethodPayload, - DashboardRequestPayload, GoogleApiModelData, GooglePayData, GpayDashboardPayLoad, Provider, + ApiModelMetaData, CardProvider, ConnectorApiIntegrationPayload, DashboardMetaData, + DashboardPaymentMethodPayload, DashboardRequestPayload, GoogleApiModelData, GooglePayData, + GpayDashboardPayLoad, Provider, }; impl ConnectorApiIntegrationPayload { @@ -275,52 +276,7 @@ impl ConnectorApiIntegrationPayload { card_provider: Some(credit_details), }; - let google_pay = Self::get_google_pay_metadata_response(response.clone()); - let account_name = match response.metadata.clone() { - Some(meta_data) => meta_data.account_name, - _ => None, - }; - - let merchant_account_id = match response.metadata.clone() { - Some(meta_data) => meta_data.merchant_account_id, - _ => None, - }; - let merchant_id = match response.metadata.clone() { - Some(meta_data) => meta_data.merchant_id, - _ => None, - }; - let terminal_id = match response.metadata.clone() { - Some(meta_data) => meta_data.terminal_id, - _ => None, - }; - let endpoint_prefix = match response.metadata.clone() { - Some(meta_data) => meta_data.endpoint_prefix, - _ => None, - }; - let apple_pay = match response.metadata.clone() { - Some(meta_data) => meta_data.apple_pay, - _ => None, - }; - let apple_pay_combined = match response.metadata.clone() { - Some(meta_data) => meta_data.apple_pay_combined, - _ => None, - }; - let merchant_config_currency = match response.metadata.clone() { - Some(meta_data) => meta_data.merchant_config_currency, - _ => None, - }; - - let meta_data = DashboardMetaData { - merchant_config_currency, - merchant_account_id, - apple_pay, - apple_pay_combined, - google_pay, - account_name, - terminal_id, - merchant_id, - endpoint_prefix, - }; + let meta_data = response.metadata.map(DashboardMetaData::from); DashboardRequestPayload { connector: response.connector_name, @@ -339,35 +295,52 @@ impl ConnectorApiIntegrationPayload { credit_details, gift_card, ]), - metadata: Some(meta_data), + metadata: meta_data, } } +} - pub fn get_google_pay_metadata_response(response: Self) -> Option { - match response.metadata { - Some(meta_data) => { - match meta_data.google_pay { - Some(google_pay) => match google_pay { - GoogleApiModelData::Standard(standard_data) => { - let data = standard_data.allowed_payment_methods.first().map( - |allowed_pm| { - allowed_pm.tokenization_specification.parameters.clone() - }, - )?; - Some(GooglePayData::Standard(GpayDashboardPayLoad { - gateway_merchant_id: data.gateway_merchant_id, - stripe_version: data.stripe_version, - stripe_publishable_key: data.stripe_publishable_key, - merchant_name: standard_data.merchant_info.merchant_name, - merchant_id: standard_data.merchant_info.merchant_id, - })) - } - GoogleApiModelData::Zen(data) => Some(GooglePayData::Zen(data)), - }, - None => None, - } - } - None => None, +impl From for DashboardMetaData { + fn from(api_model: ApiModelMetaData) -> Self { + Self { + merchant_config_currency: api_model.merchant_config_currency, + merchant_account_id: api_model.merchant_account_id, + account_name: api_model.account_name, + terminal_id: api_model.terminal_id, + merchant_id: api_model.merchant_id, + google_pay: get_google_pay_metadata_response(api_model.google_pay), + apple_pay: api_model.apple_pay, + apple_pay_combined: api_model.apple_pay_combined, + endpoint_prefix: api_model.endpoint_prefix, + mcc: api_model.mcc, + merchant_country_code: api_model.merchant_country_code, + merchant_name: api_model.merchant_name, + acquirer_bin: api_model.acquirer_bin, + acquirer_merchant_id: api_model.acquirer_merchant_id, } } } + +pub fn get_google_pay_metadata_response( + google_pay_data: Option, +) -> Option { + match google_pay_data { + Some(google_pay) => match google_pay { + GoogleApiModelData::Standard(standard_data) => { + let data = standard_data + .allowed_payment_methods + .first() + .map(|allowed_pm| allowed_pm.tokenization_specification.parameters.clone())?; + Some(GooglePayData::Standard(GpayDashboardPayLoad { + gateway_merchant_id: data.gateway_merchant_id, + stripe_version: data.stripe_version, + stripe_publishable_key: data.stripe_publishable_key, + merchant_name: standard_data.merchant_info.merchant_name, + merchant_id: standard_data.merchant_info.merchant_id, + })) + } + GoogleApiModelData::Zen(data) => Some(GooglePayData::Zen(data)), + }, + None => None, + } +} diff --git a/crates/connector_configs/src/transformer.rs b/crates/connector_configs/src/transformer.rs index 735178cd676..09a28ac2b07 100644 --- a/crates/connector_configs/src/transformer.rs +++ b/crates/connector_configs/src/transformer.rs @@ -187,6 +187,11 @@ impl DashboardRequestPayload { merchant_id: None, merchant_config_currency: None, endpoint_prefix: None, + mcc: None, + merchant_country_code: None, + merchant_name: None, + acquirer_bin: None, + acquirer_merchant_id: None, }; let meta_data = match request.metadata { Some(data) => data, @@ -201,6 +206,12 @@ impl DashboardRequestPayload { let apple_pay = meta_data.apple_pay; let apple_pay_combined = meta_data.apple_pay_combined; let merchant_config_currency = meta_data.merchant_config_currency; + let mcc = meta_data.mcc; + let merchant_country_code = meta_data.merchant_country_code; + let merchant_name = meta_data.merchant_name; + let acquirer_bin = meta_data.acquirer_bin; + let acquirer_merchant_id = meta_data.acquirer_merchant_id; + Some(ApiModelMetaData { google_pay, apple_pay, @@ -211,6 +222,11 @@ impl DashboardRequestPayload { merchant_config_currency, apple_pay_combined, endpoint_prefix, + mcc, + merchant_country_code, + merchant_name, + acquirer_bin, + acquirer_merchant_id, }) } From 9523cf4bbac488503c31640cade326095937e33c Mon Sep 17 00:00:00 2001 From: Sakil Mostak <73734619+Sakilmostak@users.noreply.github.com> Date: Wed, 27 Mar 2024 18:46:53 +0530 Subject: [PATCH 10/20] fix(core): Amount capturable remain same for `processing` status in capture (#4229) --- crates/router/src/types.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/crates/router/src/types.rs b/crates/router/src/types.rs index e0ab8131199..6f73efa832e 100644 --- a/crates/router/src/types.rs +++ b/crates/router/src/types.rs @@ -723,9 +723,9 @@ impl Capturable for PaymentsCaptureData { let intent_status = common_enums::IntentStatus::foreign_from(attempt_status); match intent_status { common_enums::IntentStatus::Succeeded - | common_enums::IntentStatus::PartiallyCaptured - | common_enums::IntentStatus::Processing => Some(0), - common_enums::IntentStatus::Cancelled + | common_enums::IntentStatus::PartiallyCaptured => Some(0), + common_enums::IntentStatus::Processing + | common_enums::IntentStatus::Cancelled | common_enums::IntentStatus::Failed | common_enums::IntentStatus::RequiresCustomerAction | common_enums::IntentStatus::RequiresMerchantAction From 65874728094bb550d6c311965fbb5f1577091bbb Mon Sep 17 00:00:00 2001 From: Prajjwal Kumar Date: Wed, 27 Mar 2024 20:26:04 +0530 Subject: [PATCH 11/20] refactor(config): allow wildcard origin for development and Docker Compose setups (#4231) --- config/development.toml | 4 ++-- config/docker_compose.toml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/config/development.toml b/config/development.toml index 8d18e63122f..5c063acf2f7 100644 --- a/config/development.toml +++ b/config/development.toml @@ -239,9 +239,9 @@ workers = 1 [cors] max_age = 30 -origins = "http://localhost:8080,http://localhost:9000" +# origins = "http://localhost:8080,http://localhost:9000" allowed_methods = "GET,POST,PUT,DELETE" -wildcard_origin = false +wildcard_origin = true [email] sender_email = "example@example.com" diff --git a/config/docker_compose.toml b/config/docker_compose.toml index ceb00ff212e..0e034f2e145 100644 --- a/config/docker_compose.toml +++ b/config/docker_compose.toml @@ -84,9 +84,9 @@ max_feed_count = 200 [cors] max_age = 30 -origins = "http://localhost:8080,http://localhost:9000" +# origins = "http://localhost:8080,http://localhost:9000" allowed_methods = "GET,POST,PUT,DELETE" -wildcard_origin = false +wildcard_origin = true [refund] max_attempts = 10 From 0f8384dde996a455920bd4127c1d0ce62d5312ba Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 28 Mar 2024 05:54:30 +0000 Subject: [PATCH 12/20] chore(version): 2024.03.28.0 --- CHANGELOG.md | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 69d68df55c4..f41ba2b094d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,28 @@ All notable changes to HyperSwitch will be documented here. - - - +## 2024.03.28.0 + +### Features + +- **connector:** [billwerk] add connector template code ([#4123](https://github.com/juspay/hyperswitch/pull/4123)) ([`37be05d`](https://github.com/juspay/hyperswitch/commit/37be05d31d97651ddaa2c67b828d24563b35d37e)) + +### Bug Fixes + +- **connectors:** Fix wallet token deserialization error ([#4133](https://github.com/juspay/hyperswitch/pull/4133)) ([`929848f`](https://github.com/juspay/hyperswitch/commit/929848f8713b45daf479ba24fb0a49b8e327b6fd)) +- **core:** Amount capturable remain same for `processing` status in capture ([#4229](https://github.com/juspay/hyperswitch/pull/4229)) ([`9523cf4`](https://github.com/juspay/hyperswitch/commit/9523cf4bbac488503c31640cade326095937e33c)) +- **euclid_wasm:** Checkout wasm metadata issue ([#4198](https://github.com/juspay/hyperswitch/pull/4198)) ([`246898f`](https://github.com/juspay/hyperswitch/commit/246898fbb00a67d5791827527ce45e01b01b232c)) +- **log:** Adding span metadata to `tokio` spawned futures ([#4118](https://github.com/juspay/hyperswitch/pull/4118)) ([`0706221`](https://github.com/juspay/hyperswitch/commit/070622125f49c4cc9c35f5ba9c634f1fef6b26d2)) +- **trustpay:** [Trustpay] Add error code mapping '800.100.100' ([#4224](https://github.com/juspay/hyperswitch/pull/4224)) ([`9798db4`](https://github.com/juspay/hyperswitch/commit/9798db4558d926a218a0ca6f7f7c4e24a187b3da)) + +### Refactors + +- **config:** Allow wildcard origin for development and Docker Compose setups ([#4231](https://github.com/juspay/hyperswitch/pull/4231)) ([`6587472`](https://github.com/juspay/hyperswitch/commit/65874728094bb550d6c311965fbb5f1577091bbb)) + +**Full Changelog:** [`2024.03.27.0...2024.03.28.0`](https://github.com/juspay/hyperswitch/compare/2024.03.27.0...2024.03.28.0) + +- - - + ## 2024.03.27.0 ### Bug Fixes From 74cd4a79526eb1a2dead87855e6a39248ec5ccb7 Mon Sep 17 00:00:00 2001 From: Amisha Prabhat <55580080+Aprabhat19@users.noreply.github.com> Date: Thu, 28 Mar 2024 12:30:11 +0530 Subject: [PATCH 13/20] feat(payment_method): API to list countries and currencies supported by a country and payment method type (#4126) Co-authored-by: Mani Chandra Dulam Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com> --- crates/api_models/src/events/payment.rs | 8 ++- crates/api_models/src/payment_methods.rs | 22 ++++++- crates/common_enums/src/enums.rs | 1 + .../router/src/core/payment_methods/cards.rs | 62 ++++++++++++++++++- crates/router/src/routes/app.rs | 53 ++++++++++------ crates/router/src/routes/lock_utils.rs | 1 + crates/router/src/routes/payment_methods.rs | 32 +++++++++- .../router/src/types/api/payment_methods.rs | 10 +-- crates/router_env/src/logger/types.rs | 2 + 9 files changed, 160 insertions(+), 31 deletions(-) diff --git a/crates/api_models/src/events/payment.rs b/crates/api_models/src/events/payment.rs index 346ee34b2cf..b26ee0ae68e 100644 --- a/crates/api_models/src/events/payment.rs +++ b/crates/api_models/src/events/payment.rs @@ -3,8 +3,9 @@ use common_utils::events::{ApiEventMetric, ApiEventsType}; use crate::{ payment_methods::{ CustomerDefaultPaymentMethodResponse, CustomerPaymentMethodsListResponse, - DefaultPaymentMethod, PaymentMethodDeleteResponse, PaymentMethodListRequest, - PaymentMethodListResponse, PaymentMethodResponse, PaymentMethodUpdate, + DefaultPaymentMethod, ListCountriesCurrenciesRequest, ListCountriesCurrenciesResponse, + PaymentMethodDeleteResponse, PaymentMethodListRequest, PaymentMethodListResponse, + PaymentMethodResponse, PaymentMethodUpdate, }, payments::{ PaymentIdType, PaymentListConstraints, PaymentListFilterConstraints, PaymentListFilters, @@ -131,6 +132,9 @@ impl ApiEventMetric for PaymentMethodListRequest { } } +impl ApiEventMetric for ListCountriesCurrenciesRequest {} + +impl ApiEventMetric for ListCountriesCurrenciesResponse {} impl ApiEventMetric for PaymentMethodListResponse {} impl ApiEventMetric for CustomerDefaultPaymentMethodResponse { diff --git a/crates/api_models/src/payment_methods.rs b/crates/api_models/src/payment_methods.rs index 37580edbc71..f08a793ebf5 100644 --- a/crates/api_models/src/payment_methods.rs +++ b/crates/api_models/src/payment_methods.rs @@ -1,4 +1,4 @@ -use std::collections::HashMap; +use std::collections::{HashMap, HashSet}; use cards::CardNumber; use common_utils::{ @@ -914,6 +914,26 @@ pub struct TokenizedCardValue1 { pub card_token: Option, } +#[derive(Debug, serde::Serialize, serde::Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct ListCountriesCurrenciesRequest { + pub connector: api_enums::Connector, + pub payment_method_type: api_enums::PaymentMethodType, +} + +#[derive(Debug, serde::Serialize, serde::Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct ListCountriesCurrenciesResponse { + pub currencies: HashSet, + pub countries: HashSet, +} + +#[derive(Debug, serde::Serialize, serde::Deserialize, Eq, Hash, PartialEq)] +pub struct CountryCodeWithName { + pub code: api_enums::CountryAlpha2, + pub name: api_enums::Country, +} + #[derive(Debug, serde::Serialize, serde::Deserialize)] #[serde(rename_all = "camelCase")] pub struct TokenizedCardValue2 { diff --git a/crates/common_enums/src/enums.rs b/crates/common_enums/src/enums.rs index 65842a4203d..bbabab3a4e7 100644 --- a/crates/common_enums/src/enums.rs +++ b/crates/common_enums/src/enums.rs @@ -1626,6 +1626,7 @@ pub enum DisputeStatus { serde::Deserialize, serde::Serialize, strum::Display, + strum::EnumIter, strum::EnumString, utoipa::ToSchema, Copy diff --git a/crates/router/src/core/payment_methods/cards.rs b/crates/router/src/core/payment_methods/cards.rs index 289654f93ed..2a6c29ce803 100644 --- a/crates/router/src/core/payment_methods/cards.rs +++ b/crates/router/src/core/payment_methods/cards.rs @@ -7,8 +7,9 @@ use api_models::{ admin::{self, PaymentMethodsEnabled}, enums::{self as api_enums}, payment_methods::{ - BankAccountTokenData, CardDetailsPaymentMethod, CardNetworkTypes, - CustomerDefaultPaymentMethodResponse, MaskedBankDetails, PaymentExperienceTypes, + BankAccountTokenData, CardDetailsPaymentMethod, CardNetworkTypes, CountryCodeWithName, + CustomerDefaultPaymentMethodResponse, ListCountriesCurrenciesRequest, + ListCountriesCurrenciesResponse, MaskedBankDetails, PaymentExperienceTypes, PaymentMethodsData, RequestPaymentMethodTypes, RequiredFieldInfo, ResponsePaymentMethodIntermediate, ResponsePaymentMethodTypes, ResponsePaymentMethodsEnabled, @@ -30,6 +31,7 @@ use domain::CustomerUpdate; use error_stack::{report, IntoReport, ResultExt}; use masking::Secret; use router_env::{instrument, tracing}; +use strum::IntoEnumIterator; use super::surcharge_decision_configs::{ perform_surcharge_decision_management_for_payment_method_list, @@ -3606,3 +3608,59 @@ pub async fn create_encrypted_payment_method_data( pm_data_encrypted } + +pub async fn list_countries_currencies_for_connector_payment_method( + state: routes::AppState, + req: ListCountriesCurrenciesRequest, +) -> errors::RouterResponse { + Ok(services::ApplicationResponse::Json( + list_countries_currencies_for_connector_payment_method_util( + state.conf.pm_filters.clone(), + req.connector, + req.payment_method_type, + ) + .await, + )) +} + +// This feature will be more efficient as a WASM function rather than as an API. +// So extracting this logic to a separate function so that it can be used in WASM as well. +pub async fn list_countries_currencies_for_connector_payment_method_util( + connector_filters: settings::ConnectorFilters, + connector: api_enums::Connector, + payment_method_type: api_enums::PaymentMethodType, +) -> ListCountriesCurrenciesResponse { + let payment_method_type = + settings::PaymentMethodFilterKey::PaymentMethodType(payment_method_type); + + let (currencies, country_codes) = connector_filters + .0 + .get(&connector.to_string()) + .and_then(|filter| filter.0.get(&payment_method_type)) + .map(|filter| (filter.currency.clone(), filter.country.clone())) + .unwrap_or_else(|| { + connector_filters + .0 + .get("default") + .and_then(|filter| filter.0.get(&payment_method_type)) + .map_or((None, None), |filter| { + (filter.currency.clone(), filter.country.clone()) + }) + }); + + let currencies = + currencies.unwrap_or_else(|| api_enums::Currency::iter().collect::>()); + let country_codes = + country_codes.unwrap_or_else(|| api_enums::CountryAlpha2::iter().collect::>()); + + ListCountriesCurrenciesResponse { + currencies, + countries: country_codes + .into_iter() + .map(|country_code| CountryCodeWithName { + code: country_code, + name: common_enums::Country::from_alpha2(country_code), + }) + .collect(), + } +} diff --git a/crates/router/src/routes/app.rs b/crates/router/src/routes/app.rs index a889a9c5744..01ed994a9d3 100644 --- a/crates/router/src/routes/app.rs +++ b/crates/router/src/routes/app.rs @@ -19,8 +19,6 @@ use tokio::sync::oneshot; #[cfg(feature = "olap")] use super::blocklist; -#[cfg(any(feature = "olap", feature = "oltp"))] -use super::currency; #[cfg(feature = "dummy_connector")] use super::dummy_connector::*; #[cfg(feature = "payouts")] @@ -39,8 +37,10 @@ use super::{ use super::{cache::*, health::*}; #[cfg(any(feature = "olap", feature = "oltp"))] use super::{configs::*, customers::*, mandates::*, payments::*, refunds::*}; +#[cfg(any(feature = "olap", feature = "oltp"))] +use super::{currency, payment_methods::*}; #[cfg(feature = "oltp")] -use super::{ephemeral_key::*, payment_methods::*, webhooks::*}; +use super::{ephemeral_key::*, webhooks::*}; use crate::configs::secrets_transformers; #[cfg(all(feature = "frm", feature = "oltp"))] use crate::routes::fraud_check as frm_routes; @@ -738,24 +738,39 @@ impl Payouts { pub struct PaymentMethods; -#[cfg(feature = "oltp")] +#[cfg(any(feature = "olap", feature = "oltp"))] impl PaymentMethods { pub fn server(state: AppState) -> Scope { - web::scope("/payment_methods") - .app_data(web::Data::new(state)) - .service( - web::resource("") - .route(web::post().to(create_payment_method_api)) - .route(web::get().to(list_payment_method_api)), // TODO : added for sdk compatibility for now, need to deprecate this later - ) - .service( - web::resource("/{payment_method_id}") - .route(web::get().to(payment_method_retrieve_api)) - .route(web::post().to(payment_method_update_api)) - .route(web::delete().to(payment_method_delete_api)), - ) - .service(web::resource("/auth/link").route(web::post().to(pm_auth::link_token_create))) - .service(web::resource("/auth/exchange").route(web::post().to(pm_auth::exchange_token))) + let mut route = web::scope("/payment_methods").app_data(web::Data::new(state)); + #[cfg(feature = "olap")] + { + route = route.service( + web::resource("/filter") + .route(web::get().to(list_countries_currencies_for_connector_payment_method)), + ); + } + #[cfg(feature = "oltp")] + { + route = route + .service( + web::resource("") + .route(web::post().to(create_payment_method_api)) + .route(web::get().to(list_payment_method_api)), // TODO : added for sdk compatibility for now, need to deprecate this later + ) + .service( + web::resource("/{payment_method_id}") + .route(web::get().to(payment_method_retrieve_api)) + .route(web::post().to(payment_method_update_api)) + .route(web::delete().to(payment_method_delete_api)), + ) + .service( + web::resource("/auth/link").route(web::post().to(pm_auth::link_token_create)), + ) + .service( + web::resource("/auth/exchange").route(web::post().to(pm_auth::exchange_token)), + ) + } + route } } diff --git a/crates/router/src/routes/lock_utils.rs b/crates/router/src/routes/lock_utils.rs index 4826a72f9d1..7908b9dfdca 100644 --- a/crates/router/src/routes/lock_utils.rs +++ b/crates/router/src/routes/lock_utils.rs @@ -97,6 +97,7 @@ impl From for ApiIdentifier { | Flow::PaymentMethodsUpdate | Flow::PaymentMethodsDelete | Flow::ValidatePaymentMethod + | Flow::ListCountriesCurrencies | Flow::DefaultPaymentMethodsSet => Self::PaymentMethods, Flow::PmAuthLinkTokenCreate | Flow::PmAuthExchangeToken => Self::PaymentMethodAuth, diff --git a/crates/router/src/routes/payment_methods.rs b/crates/router/src/routes/payment_methods.rs index 1e2e66d583c..7ef20994e2e 100644 --- a/crates/router/src/routes/payment_methods.rs +++ b/crates/router/src/routes/payment_methods.rs @@ -8,7 +8,7 @@ use time::PrimitiveDateTime; use super::app::AppState; use crate::{ core::{api_locking, errors, payment_methods::cards}, - services::{api, authentication as auth}, + services::{api, authentication as auth, authorization::permissions::Permission}, types::{ api::payment_methods::{self, PaymentMethodId}, storage::payment_method::PaymentTokenData, @@ -262,6 +262,35 @@ pub async fn payment_method_delete_api( .await } +#[instrument(skip_all, fields(flow = ?Flow::ListCountriesCurrencies))] +pub async fn list_countries_currencies_for_connector_payment_method( + state: web::Data, + req: HttpRequest, + query_payload: web::Query, +) -> HttpResponse { + let flow = Flow::ListCountriesCurrencies; + let payload = query_payload.into_inner(); + Box::pin(api::server_wrap( + flow, + state, + &req, + payload, + |state, _auth: auth::AuthenticationData, req| { + cards::list_countries_currencies_for_connector_payment_method(state, req) + }, + #[cfg(not(feature = "release"))] + auth::auth_type( + &auth::ApiKeyAuth, + &auth::JWTAuth(Permission::MerchantConnectorAccountWrite), + req.headers(), + ), + #[cfg(feature = "release")] + &auth::JWTAuth(Permission::MerchantConnectorAccountWrite), + api_locking::LockAction::NotApplicable, + )) + .await +} + #[instrument(skip_all, fields(flow = ?Flow::DefaultPaymentMethodsSet))] pub async fn default_payment_method_set_api( state: web::Data, @@ -297,7 +326,6 @@ pub async fn default_payment_method_set_api( )) .await } - #[cfg(test)] mod tests { #![allow(clippy::unwrap_used)] diff --git a/crates/router/src/types/api/payment_methods.rs b/crates/router/src/types/api/payment_methods.rs index 642e94ad69e..13c9ec61f2a 100644 --- a/crates/router/src/types/api/payment_methods.rs +++ b/crates/router/src/types/api/payment_methods.rs @@ -1,11 +1,11 @@ pub use api_models::payment_methods::{ CardDetail, CardDetailFromLocker, CardDetailsPaymentMethod, CustomerPaymentMethod, CustomerPaymentMethodsListResponse, DefaultPaymentMethod, DeleteTokenizeByTokenRequest, - GetTokenizePayloadRequest, GetTokenizePayloadResponse, PaymentMethodCreate, - PaymentMethodDeleteResponse, PaymentMethodId, PaymentMethodList, PaymentMethodListRequest, - PaymentMethodListResponse, PaymentMethodResponse, PaymentMethodUpdate, PaymentMethodsData, - TokenizePayloadEncrypted, TokenizePayloadRequest, TokenizedCardValue1, TokenizedCardValue2, - TokenizedWalletValue1, TokenizedWalletValue2, + GetTokenizePayloadRequest, GetTokenizePayloadResponse, ListCountriesCurrenciesRequest, + PaymentMethodCreate, PaymentMethodDeleteResponse, PaymentMethodId, PaymentMethodList, + PaymentMethodListRequest, PaymentMethodListResponse, PaymentMethodResponse, + PaymentMethodUpdate, PaymentMethodsData, TokenizePayloadEncrypted, TokenizePayloadRequest, + TokenizedCardValue1, TokenizedCardValue2, TokenizedWalletValue1, TokenizedWalletValue2, }; use error_stack::report; diff --git a/crates/router_env/src/logger/types.rs b/crates/router_env/src/logger/types.rs index 363a41ad43a..df322da9429 100644 --- a/crates/router_env/src/logger/types.rs +++ b/crates/router_env/src/logger/types.rs @@ -117,6 +117,8 @@ pub enum Flow { CustomerPaymentMethodsList, /// List Customers for a merchant CustomersList, + /// Retrieve countries and currencies for connector and payment method + ListCountriesCurrencies, /// Payment methods retrieve flow. PaymentMethodsRetrieve, /// Payment methods update flow. From e8289f061d4735478cb1521de50f696d2412ad33 Mon Sep 17 00:00:00 2001 From: Pa1NarK <69745008+pixincreate@users.noreply.github.com> Date: Thu, 28 Mar 2024 13:30:37 +0530 Subject: [PATCH 14/20] chore(config): add billwerk base URL in deployment configs (#4243) --- config/deployments/integration_test.toml | 3 ++- config/deployments/production.toml | 3 ++- config/deployments/sandbox.toml | 13 +++++++------ 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/config/deployments/integration_test.toml b/config/deployments/integration_test.toml index 6d4cc21c3a3..10776c76678 100644 --- a/config/deployments/integration_test.toml +++ b/config/deployments/integration_test.toml @@ -20,6 +20,7 @@ applepay.base_url = "https://apple-pay-gateway.apple.com/" authorizedotnet.base_url = "https://apitest.authorize.net/xml/v1/request.api" bambora.base_url = "https://api.na.bambora.com" bankofamerica.base_url = "https://apitest.merchant-services.bankofamerica.com/" +billwerk.base_url = "https://api.reepay.com/" bitpay.base_url = "https://test.bitpay.com" bluesnap.base_url = "https://sandbox.bluesnap.com/" bluesnap.secondary_base_url = "https://sandpay.bluesnap.com/" @@ -299,4 +300,4 @@ outgoing_enabled = true connectors_with_webhook_source_verification_call = "paypal" [unmasked_headers] -keys = "user-agent" \ No newline at end of file +keys = "user-agent" diff --git a/config/deployments/production.toml b/config/deployments/production.toml index 7c8105795b8..a6405e4a3b2 100644 --- a/config/deployments/production.toml +++ b/config/deployments/production.toml @@ -24,6 +24,7 @@ applepay.base_url = "https://apple-pay-gateway.apple.com/" authorizedotnet.base_url = "https://api.authorize.net/xml/v1/request.api" bambora.base_url = "https://api.na.bambora.com" bankofamerica.base_url = "https://api.merchant-services.bankofamerica.com/" +billwerk.base_url = "https://api.reepay.com/" bitpay.base_url = "https://bitpay.com" bluesnap.base_url = "https://ws.bluesnap.com/" bluesnap.secondary_base_url = "https://pay.bluesnap.com/" @@ -313,4 +314,4 @@ outgoing_enabled = true connectors_with_webhook_source_verification_call = "paypal" [unmasked_headers] -keys = "user-agent" \ No newline at end of file +keys = "user-agent" diff --git a/config/deployments/sandbox.toml b/config/deployments/sandbox.toml index faf329db74c..035c90af378 100644 --- a/config/deployments/sandbox.toml +++ b/config/deployments/sandbox.toml @@ -24,6 +24,7 @@ applepay.base_url = "https://apple-pay-gateway.apple.com/" authorizedotnet.base_url = "https://apitest.authorize.net/xml/v1/request.api" bambora.base_url = "https://api.na.bambora.com" bankofamerica.base_url = "https://apitest.merchant-services.bankofamerica.com/" +billwerk.base_url = "https://api.reepay.com/" bitpay.base_url = "https://test.bitpay.com" bluesnap.base_url = "https://sandbox.bluesnap.com/" bluesnap.secondary_base_url = "https://sandpay.bluesnap.com/" @@ -123,8 +124,8 @@ bank_redirect.sofort.connector_list = "stripe,adyen,globalpay" bank_redirect.giropay.connector_list = "adyen,globalpay" [mandates.update_mandate_supported] -card.credit ={connector_list ="cybersource"} -card.debit = {connector_list ="cybersource"} +card.credit = { connector_list = "cybersource" } +card.debit = { connector_list = "cybersource" } [multiple_api_version_supported_connectors] supported_connectors = "braintree" @@ -190,7 +191,7 @@ google_pay = { country = "AU,NZ,JP,HK,SG,MY,TH,VN,BH,AE,KW,BR,ES,GB,SE,NO,SK,AT, ideal = { country = "NL", currency = "EUR" } indomaret = { country = "ID", currency = "IDR" } kakao_pay = { country = "KR", currency = "KRW" } -klarna = { country = "AU,AT,BE,CA,CZ,DK,FI,FR,DE,GR,IE,IT,NO,PL,PT,RO,ES,SE,CH,NL,GB,US", currency = "AUD,EUR,CAD,CZK,DKK,NOK,PLN,RON,SEK,CHF,GBP,USD"} +klarna = { country = "AU,AT,BE,CA,CZ,DK,FI,FR,DE,GR,IE,IT,NO,PL,PT,RO,ES,SE,CH,NL,GB,US", currency = "AUD,EUR,CAD,CZK,DKK,NOK,PLN,RON,SEK,CHF,GBP,USD" } lawson = { country = "JP", currency = "JPY" } mandiri_va = { country = "ID", currency = "IDR" } mb_way = { country = "PT", currency = "EUR" } @@ -214,7 +215,7 @@ permata_bank_transfer = { country = "ID", currency = "IDR" } seicomart = { country = "JP", currency = "JPY" } sepa = { country = "ES,SK,AT,NL,DE,BE,FR,FI,PT,IE,EE,LT,LV,IT", currency = "EUR" } seven_eleven = { country = "JP", currency = "JPY" } -sofort = { country = "AT,BE,DE,ES,CH,NL", currency = "CHF,EUR"} +sofort = { country = "AT,BE,DE,ES,CH,NL", currency = "CHF,EUR" } swish = { country = "SE", currency = "SEK" } touch_n_go = { country = "MY", currency = "MYR" } trustly = { country = "ES,GB,SE,NO,AT,NL,DE,DK,FI,EE,LT,LV", currency = "CZK,DKK,EUR,GBP,NOK,SEK" } @@ -271,7 +272,7 @@ klarna = { country = "AU,AT,BE,CA,CZ,DK,FI,FR,DE,GR,IE,IT,NL,NZ,NO,PL,PT,ES,SE,C sofort = { country = "AT,BE,DE,IT,NL,ES", currency = "EUR" } [pm_filters.volt] -open_banking_uk = {country = "DE,GB,AT,BE,CY,EE,ES,FI,FR,GR,HR,IE,IT,LT,LU,LV,MT,NL,PT,SI,SK,BG,CZ,DK,HU,NO,PL,RO,SE,AU,BR", currency = "EUR,GBP,DKK,NOK,PLN,SEK,AUD,BRL"} +open_banking_uk = { country = "DE,GB,AT,BE,CY,EE,ES,FI,FR,GR,HR,IE,IT,LT,LU,LV,MT,NL,PT,SI,SK,BG,CZ,DK,HU,NO,PL,RO,SE,AU,BR", currency = "EUR,GBP,DKK,NOK,PLN,SEK,AUD,BRL" } [pm_filters.worldpay] apple_pay.country = "AU,CN,HK,JP,MO,MY,NZ,SG,TW,AM,AT,AZ,BY,BE,BG,HR,CY,CZ,DK,EE,FO,FI,FR,GE,DE,GR,GL,GG,HU,IS,IE,IM,IT,KZ,JE,LV,LI,LT,LU,MT,MD,MC,ME,NL,NO,PL,PT,RO,SM,RS,SK,SI,ES,SE,CH,UA,GB,AR,CO,CR,BR,MX,PE,BH,IL,JO,KW,PS,QA,SA,AE,CA,UM,US" @@ -315,4 +316,4 @@ outgoing_enabled = true connectors_with_webhook_source_verification_call = "paypal" [unmasked_headers] -keys = "user-agent" \ No newline at end of file +keys = "user-agent" From ffb3f4be012bcbb186ad19ba895fb8cfc04c63c2 Mon Sep 17 00:00:00 2001 From: Sanchith Hegde <22217505+SanchithHegde@users.noreply.github.com> Date: Thu, 28 Mar 2024 15:50:28 +0530 Subject: [PATCH 15/20] ci(CI-pr): determine modified crates more deterministically (#4233) --- .github/workflows/CI-pr.yml | 12 ++++++++++-- crates/api_models/src/bank_accounts.rs | 1 - crates/api_models/src/lib.rs | 1 - 3 files changed, 10 insertions(+), 4 deletions(-) delete mode 100644 crates/api_models/src/bank_accounts.rs diff --git a/.github/workflows/CI-pr.yml b/.github/workflows/CI-pr.yml index efeb31cd1e8..9794afc155d 100644 --- a/.github/workflows/CI-pr.yml +++ b/.github/workflows/CI-pr.yml @@ -141,7 +141,11 @@ jobs: # Obtain a list of workspace members workspace_members="$( cargo metadata --format-version 1 --no-deps \ - | jq --compact-output --monochrome-output --raw-output '.workspace_members | sort | .[] | split(" ")[0]' + | jq \ + --compact-output \ + --monochrome-output \ + --raw-output \ + '(.workspace_members | sort) as $package_ids | .packages[] | select(IN(.id; $package_ids[])) | .name' )" PACKAGES_CHECKED=() @@ -298,7 +302,11 @@ jobs: # Obtain a list of workspace members workspace_members="$( cargo metadata --format-version 1 --no-deps \ - | jq --compact-output --monochrome-output --raw-output '.workspace_members | sort | .[] | split(" ")[0]' + | jq \ + --compact-output \ + --monochrome-output \ + --raw-output \ + '(.workspace_members | sort) as $package_ids | .packages[] | select(IN(.id; $package_ids[])) | .name' )" PACKAGES_CHECKED=() diff --git a/crates/api_models/src/bank_accounts.rs b/crates/api_models/src/bank_accounts.rs deleted file mode 100644 index 8b137891791..00000000000 --- a/crates/api_models/src/bank_accounts.rs +++ /dev/null @@ -1 +0,0 @@ - diff --git a/crates/api_models/src/lib.rs b/crates/api_models/src/lib.rs index cc991d7a6b8..89097705a40 100644 --- a/crates/api_models/src/lib.rs +++ b/crates/api_models/src/lib.rs @@ -2,7 +2,6 @@ pub mod admin; pub mod analytics; pub mod api_keys; -pub mod bank_accounts; pub mod blocklist; pub mod cards_info; pub mod conditional_configs; From 7b337ac39d72f90dd0ebe58133218896ff279313 Mon Sep 17 00:00:00 2001 From: Chethan Rao <70657455+Chethan-rao@users.noreply.github.com> Date: Thu, 28 Mar 2024 18:12:30 +0530 Subject: [PATCH 16/20] feat(mandates): allow off-session payments using `payment_method_id` (#4132) Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com> --- crates/api_models/src/mandates.rs | 7 + crates/api_models/src/payments.rs | 21 +- crates/openapi/src/openapi.rs | 1 + crates/router/src/core/mandate/helpers.rs | 19 +- crates/router/src/core/payments.rs | 148 ++++++------ crates/router/src/core/payments/helpers.rs | 219 ++++++++++++------ .../payments/operations/payment_approve.rs | 1 + .../payments/operations/payment_cancel.rs | 1 + .../payments/operations/payment_capture.rs | 1 + .../operations/payment_complete_authorize.rs | 20 +- .../payments/operations/payment_confirm.rs | 18 +- .../payments/operations/payment_create.rs | 28 ++- .../payments/operations/payment_reject.rs | 1 + .../payments/operations/payment_session.rs | 1 + .../core/payments/operations/payment_start.rs | 1 + .../payments/operations/payment_status.rs | 1 + .../payments/operations/payment_update.rs | 33 ++- .../payments_incremental_authorization.rs | 1 + crates/router/src/types/api/payments.rs | 5 +- openapi/openapi_spec.json | 75 ++++++ 20 files changed, 429 insertions(+), 173 deletions(-) diff --git a/crates/api_models/src/mandates.rs b/crates/api_models/src/mandates.rs index bd5c5b5a1a0..4adda0d9af4 100644 --- a/crates/api_models/src/mandates.rs +++ b/crates/api_models/src/mandates.rs @@ -113,3 +113,10 @@ pub struct MandateListConstraints { #[serde(rename = "created_time.gte")] pub created_time_gte: Option, } + +#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, ToSchema)] +#[serde(tag = "type", content = "data", rename_all = "snake_case")] +pub enum RecurringDetails { + MandateId(String), + PaymentMethodId(String), +} diff --git a/crates/api_models/src/payments.rs b/crates/api_models/src/payments.rs index ce2b1c3d68a..72592ec3cad 100644 --- a/crates/api_models/src/payments.rs +++ b/crates/api_models/src/payments.rs @@ -19,10 +19,8 @@ use url::Url; use utoipa::ToSchema; use crate::{ - admin, disputes, - enums::{self as api_enums}, - ephemeral_key::EphemeralKeyCreateResponse, - refunds, + admin, disputes, enums as api_enums, ephemeral_key::EphemeralKeyCreateResponse, + mandates::RecurringDetails, refunds, }; #[derive(Clone, Copy, Debug, Eq, PartialEq)] @@ -459,6 +457,9 @@ pub struct PaymentsRequest { /// Whether to perform external authentication (if applicable) #[schema(example = true)] pub request_external_three_ds_authentication: Option, + + /// Details required for recurring payment + pub recurring_details: Option, } impl PaymentsRequest { @@ -3360,7 +3361,7 @@ pub struct PaymentsRedirectionResponse { } pub struct MandateValidationFields { - pub mandate_id: Option, + pub recurring_details: Option, pub confirm: Option, pub customer_id: Option, pub mandate_data: Option, @@ -3370,8 +3371,14 @@ pub struct MandateValidationFields { impl From<&PaymentsRequest> for MandateValidationFields { fn from(req: &PaymentsRequest) -> Self { + let recurring_details = req + .mandate_id + .clone() + .map(RecurringDetails::MandateId) + .or(req.recurring_details.clone()); + Self { - mandate_id: req.mandate_id.clone(), + recurring_details, confirm: req.confirm, customer_id: req .customer @@ -3389,7 +3396,7 @@ impl From<&PaymentsRequest> for MandateValidationFields { impl From<&VerifyRequest> for MandateValidationFields { fn from(req: &VerifyRequest) -> Self { Self { - mandate_id: None, + recurring_details: None, confirm: Some(true), customer_id: req.customer_id.clone(), mandate_data: req.mandate_data.clone(), diff --git a/crates/openapi/src/openapi.rs b/crates/openapi/src/openapi.rs index c8e89f2ee70..4a61a20d08d 100644 --- a/crates/openapi/src/openapi.rs +++ b/crates/openapi/src/openapi.rs @@ -410,6 +410,7 @@ Never share your secret api keys. Keep them guarded and secure. api_models::mandates::MandateRevokedResponse, api_models::mandates::MandateResponse, api_models::mandates::MandateCardDetails, + api_models::mandates::RecurringDetails, api_models::ephemeral_key::EphemeralKeyCreateResponse, api_models::payments::CustomerDetails, api_models::payments::GiftCardData, diff --git a/crates/router/src/core/mandate/helpers.rs b/crates/router/src/core/mandate/helpers.rs index 150130ed9e5..704b7ae99f5 100644 --- a/crates/router/src/core/mandate/helpers.rs +++ b/crates/router/src/core/mandate/helpers.rs @@ -1,8 +1,14 @@ +use common_enums::enums; use common_utils::errors::CustomResult; +use data_models::mandates::MandateData; use diesel_models::Mandate; use error_stack::ResultExt; -use crate::{core::errors, routes::AppState, types::domain}; +use crate::{ + core::{errors, payments}, + routes::AppState, + types::domain, +}; pub async fn get_profile_id_for_mandate( state: &AppState, @@ -33,3 +39,14 @@ pub async fn get_profile_id_for_mandate( }?; Ok(profile_id) } + +#[derive(Clone)] +pub struct MandateGenericData { + pub token: Option, + pub payment_method: Option, + pub payment_method_type: Option, + pub mandate_data: Option, + pub recurring_mandate_payment_data: Option, + pub mandate_connector: Option, + pub payment_method_info: Option, +} diff --git a/crates/router/src/core/payments.rs b/crates/router/src/core/payments.rs index 0a3a93923b7..e11a77496af 100644 --- a/crates/router/src/core/payments.rs +++ b/crates/router/src/core/payments.rs @@ -15,6 +15,7 @@ use std::{fmt::Debug, marker::PhantomData, ops::Deref, time::Instant, vec::IntoI use api_models::{ self, enums, + mandates::RecurringDetails, payments::{self as payments_api, HeaderPayload}, }; use common_utils::{ext_traits::AsyncExt, pii, types::Surcharge}; @@ -2263,6 +2264,7 @@ where pub authorizations: Vec, pub authentication: Option, pub frm_metadata: Option, + pub recurring_details: Option, } #[derive(Debug, Default, Clone)] @@ -2907,7 +2909,7 @@ where .change_context(errors::ApiErrorResponse::InternalServerError) .attach_printable("Invalid connector name received")?; - return decide_connector_for_token_based_mit_flow( + return decide_multiplex_connector_for_normal_or_recurring_payment( payment_data, routing_data, connector_data, @@ -2961,7 +2963,7 @@ where .change_context(errors::ApiErrorResponse::InternalServerError) .attach_printable("Invalid connector name received")?; - return decide_connector_for_token_based_mit_flow( + return decide_multiplex_connector_for_normal_or_recurring_payment( payment_data, routing_data, connector_data, @@ -2980,24 +2982,26 @@ where .await } -pub fn decide_connector_for_token_based_mit_flow( +pub fn decide_multiplex_connector_for_normal_or_recurring_payment( payment_data: &mut PaymentData, routing_data: &mut storage::RoutingData, connectors: Vec, ) -> RouterResult { - if let Some((storage_enums::FutureUsage::OffSession, _)) = payment_data - .payment_intent - .setup_future_usage - .zip(payment_data.token_data.as_ref()) - { - logger::debug!("performing routing for token-based MIT flow"); + match ( + payment_data.payment_intent.setup_future_usage, + payment_data.token_data.as_ref(), + payment_data.recurring_details.as_ref(), + ) { + (Some(storage_enums::FutureUsage::OffSession), Some(_), None) + | (None, None, Some(RecurringDetails::PaymentMethodId(_))) => { + logger::debug!("performing routing for token-based MIT flow"); - let payment_method_info = payment_data - .payment_method_info - .as_ref() - .get_required_value("payment_method_info")?; + let payment_method_info = payment_data + .payment_method_info + .as_ref() + .get_required_value("payment_method_info")?; - let connector_mandate_details = payment_method_info + let connector_mandate_details = payment_method_info .connector_mandate_details .clone() .map(|details| { @@ -3010,67 +3014,69 @@ pub fn decide_connector_for_token_based_mit_flow( .change_context(errors::ApiErrorResponse::IncorrectPaymentMethodConfiguration) .attach_printable("no eligible connector found for token-based MIT flow since there were no connector mandate details")?; - let mut connector_choice = None; - for connector_data in connectors { - if let Some(merchant_connector_id) = connector_data.merchant_connector_id.as_ref() { - if let Some(mandate_reference_record) = - connector_mandate_details.get(merchant_connector_id) - { - connector_choice = Some((connector_data, mandate_reference_record.clone())); - break; + let mut connector_choice = None; + for connector_data in connectors { + if let Some(merchant_connector_id) = connector_data.merchant_connector_id.as_ref() { + if let Some(mandate_reference_record) = + connector_mandate_details.get(merchant_connector_id) + { + connector_choice = Some((connector_data, mandate_reference_record.clone())); + break; + } } } - } - let (chosen_connector_data, mandate_reference_record) = connector_choice - .get_required_value("connector_choice") - .change_context(errors::ApiErrorResponse::IncorrectPaymentMethodConfiguration) - .attach_printable("no eligible connector found for token-based MIT payment")?; + let (chosen_connector_data, mandate_reference_record) = connector_choice + .get_required_value("connector_choice") + .change_context(errors::ApiErrorResponse::IncorrectPaymentMethodConfiguration) + .attach_printable("no eligible connector found for token-based MIT payment")?; - routing_data.routed_through = Some(chosen_connector_data.connector_name.to_string()); - #[cfg(feature = "connector_choice_mca_id")] - { - routing_data.merchant_connector_id = - chosen_connector_data.merchant_connector_id.clone(); - } + routing_data.routed_through = Some(chosen_connector_data.connector_name.to_string()); + #[cfg(feature = "connector_choice_mca_id")] + { + routing_data.merchant_connector_id = + chosen_connector_data.merchant_connector_id.clone(); + } - payment_data.mandate_id = Some(payments_api::MandateIds { - mandate_id: None, - mandate_reference_id: Some(payments_api::MandateReferenceId::ConnectorMandateId( - payments_api::ConnectorMandateReferenceId { - connector_mandate_id: Some( - mandate_reference_record.connector_mandate_id.clone(), - ), - payment_method_id: Some(payment_method_info.payment_method_id.clone()), - update_history: None, - }, - )), - }); - - payment_data.recurring_mandate_payment_data = Some(RecurringMandatePaymentData { - payment_method_type: mandate_reference_record.payment_method_type, - original_payment_authorized_amount: mandate_reference_record - .original_payment_authorized_amount, - original_payment_authorized_currency: mandate_reference_record - .original_payment_authorized_currency, - }); - - Ok(api::ConnectorCallType::PreDetermined(chosen_connector_data)) - } else { - let first_choice = connectors - .first() - .ok_or(errors::ApiErrorResponse::IncorrectPaymentMethodConfiguration) - .into_report() - .attach_printable("no eligible connector found for payment")? - .clone(); - - routing_data.routed_through = Some(first_choice.connector_name.to_string()); - #[cfg(feature = "connector_choice_mca_id")] - { - routing_data.merchant_connector_id = first_choice.merchant_connector_id; + payment_data.mandate_id = Some(payments_api::MandateIds { + mandate_id: None, + mandate_reference_id: Some(payments_api::MandateReferenceId::ConnectorMandateId( + payments_api::ConnectorMandateReferenceId { + connector_mandate_id: Some( + mandate_reference_record.connector_mandate_id.clone(), + ), + payment_method_id: Some(payment_method_info.payment_method_id.clone()), + update_history: None, + }, + )), + }); + + payment_data.recurring_mandate_payment_data = Some(RecurringMandatePaymentData { + payment_method_type: mandate_reference_record.payment_method_type, + original_payment_authorized_amount: mandate_reference_record + .original_payment_authorized_amount, + original_payment_authorized_currency: mandate_reference_record + .original_payment_authorized_currency, + }); + + Ok(api::ConnectorCallType::PreDetermined(chosen_connector_data)) } + _ => { + let first_choice = connectors + .first() + .ok_or(errors::ApiErrorResponse::IncorrectPaymentMethodConfiguration) + .into_report() + .attach_printable("no eligible connector found for payment")? + .clone(); + + routing_data.routed_through = Some(first_choice.connector_name.to_string()); + #[cfg(feature = "connector_choice_mca_id")] + { + routing_data.merchant_connector_id = first_choice.merchant_connector_id; + } - Ok(api::ConnectorCallType::Retryable(connectors)) + Ok(api::ConnectorCallType::Retryable(connectors)) + } } } @@ -3291,7 +3297,11 @@ where match transaction_data { TransactionData::Payment(payment_data) => { - decide_connector_for_token_based_mit_flow(payment_data, routing_data, connector_data) + decide_multiplex_connector_for_normal_or_recurring_payment( + payment_data, + routing_data, + connector_data, + ) } #[cfg(feature = "payouts")] diff --git a/crates/router/src/core/payments/helpers.rs b/crates/router/src/core/payments/helpers.rs index 7eab4c0d26a..e9cefbf8aed 100644 --- a/crates/router/src/core/payments/helpers.rs +++ b/crates/router/src/core/payments/helpers.rs @@ -1,6 +1,9 @@ use std::borrow::Cow; -use api_models::payments::{CardToken, GetPaymentMethodType, RequestSurchargeDetails}; +use api_models::{ + mandates::RecurringDetails, + payments::{CardToken, GetPaymentMethodType, RequestSurchargeDetails}, +}; use base64::Engine; use common_utils::{ ext_traits::{AsyncExt, ByteSliceExt, Encode, ValueExt}, @@ -34,6 +37,7 @@ use crate::{ consts::{self, BASE64_ENGINE}, core::{ errors::{self, CustomResult, RouterResult, StorageErrorExt}, + mandate::helpers::MandateGenericData, payment_methods::{cards, vault, PaymentMethodRetrieve}, payments, pm_auth::retrieve_payment_method_from_auth_service, @@ -414,59 +418,117 @@ pub async fn get_token_pm_type_mandate_details( mandate_type: Option, merchant_account: &domain::MerchantAccount, merchant_key_store: &domain::MerchantKeyStore, -) -> RouterResult<( - Option, - Option, - Option, - Option, - Option, - Option, -)> { +) -> RouterResult { let mandate_data = request.mandate_data.clone().map(MandateData::foreign_from); - match mandate_type { - Some(api::MandateTransactionType::NewMandateTransaction) => { - let setup_mandate = mandate_data.clone().get_required_value("mandate_data")?; - Ok(( - request.payment_token.to_owned(), - request.payment_method, - request.payment_method_type, - Some(setup_mandate), - None, - None, - )) - } + let ( + payment_token, + payment_method, + payment_method_type, + mandate_data, + recurring_payment_data, + mandate_connector_details, + payment_method_info, + ) = match mandate_type { + Some(api::MandateTransactionType::NewMandateTransaction) => ( + request.payment_token.to_owned(), + request.payment_method, + request.payment_method_type, + Some(mandate_data.clone().get_required_value("mandate_data")?), + None, + None, + None, + ), Some(api::MandateTransactionType::RecurringMandateTransaction) => { - let ( - token_, - payment_method_, - recurring_mandate_payment_data, - payment_method_type_, - mandate_connector, - ) = get_token_for_recurring_mandate( - state, - request, - merchant_account, - merchant_key_store, - ) - .await?; - Ok(( - token_, - payment_method_, - payment_method_type_.or(request.payment_method_type), - None, - recurring_mandate_payment_data, - mandate_connector, - )) + match &request.recurring_details { + Some(recurring_details) => match recurring_details { + RecurringDetails::MandateId(mandate_id) => { + let mandate_generic_data = get_token_for_recurring_mandate( + state, + request, + merchant_account, + merchant_key_store, + mandate_id.to_owned(), + ) + .await?; + + ( + mandate_generic_data.token, + mandate_generic_data.payment_method, + mandate_generic_data + .payment_method_type + .or(request.payment_method_type), + None, + mandate_generic_data.recurring_mandate_payment_data, + mandate_generic_data.mandate_connector, + None, + ) + } + RecurringDetails::PaymentMethodId(payment_method_id) => { + let payment_method_info = state + .store + .find_payment_method(payment_method_id) + .await + .to_not_found_response( + errors::ApiErrorResponse::PaymentMethodNotFound, + )?; + + ( + None, + Some(payment_method_info.payment_method), + payment_method_info.payment_method_type, + None, + None, + None, + Some(payment_method_info), + ) + } + }, + None => { + let mandate_id = request + .mandate_id + .clone() + .get_required_value("mandate_id")?; + let mandate_generic_data = get_token_for_recurring_mandate( + state, + request, + merchant_account, + merchant_key_store, + mandate_id, + ) + .await?; + ( + mandate_generic_data.token, + mandate_generic_data.payment_method, + mandate_generic_data + .payment_method_type + .or(request.payment_method_type), + None, + mandate_generic_data.recurring_mandate_payment_data, + mandate_generic_data.mandate_connector, + None, + ) + } + } } - None => Ok(( + None => ( request.payment_token.to_owned(), request.payment_method, request.payment_method_type, mandate_data, None, None, - )), - } + None, + ), + }; + Ok(MandateGenericData { + token: payment_token, + payment_method, + payment_method_type, + mandate_data, + recurring_mandate_payment_data: recurring_payment_data, + mandate_connector: mandate_connector_details, + payment_method_info, + }) } pub async fn get_token_for_recurring_mandate( @@ -474,15 +536,9 @@ pub async fn get_token_for_recurring_mandate( req: &api::PaymentsRequest, merchant_account: &domain::MerchantAccount, merchant_key_store: &domain::MerchantKeyStore, -) -> RouterResult<( - Option, - Option, - Option, - Option, - Option, -)> { + mandate_id: String, +) -> RouterResult { let db = &*state.store; - let mandate_id = req.mandate_id.clone().get_required_value("mandate_id")?; let mandate = db .find_mandate_by_merchant_id_mandate_id(&merchant_account.merchant_id, mandate_id.as_str()) @@ -566,29 +622,33 @@ pub async fn get_token_for_recurring_mandate( } }; - Ok(( - Some(token), - Some(payment_method.payment_method), - Some(payments::RecurringMandatePaymentData { + Ok(MandateGenericData { + token: Some(token), + payment_method: Some(payment_method.payment_method), + recurring_mandate_payment_data: Some(payments::RecurringMandatePaymentData { payment_method_type, original_payment_authorized_amount, original_payment_authorized_currency, }), - payment_method.payment_method_type, - Some(mandate_connector_details), - )) + payment_method_type: payment_method.payment_method_type, + mandate_connector: Some(mandate_connector_details), + mandate_data: None, + payment_method_info: None, + }) } else { - Ok(( - None, - Some(payment_method.payment_method), - Some(payments::RecurringMandatePaymentData { + Ok(MandateGenericData { + token: None, + payment_method: Some(payment_method.payment_method), + recurring_mandate_payment_data: Some(payments::RecurringMandatePaymentData { payment_method_type, original_payment_authorized_amount, original_payment_authorized_currency, }), - payment_method.payment_method_type, - Some(mandate_connector_details), - )) + payment_method_type: payment_method.payment_method_type, + mandate_connector: Some(mandate_connector_details), + mandate_data: None, + payment_method_info: None, + }) } } @@ -792,7 +852,7 @@ pub fn validate_mandate( let req: api::MandateValidationFields = req.into(); match req.validate_and_get_mandate_type().change_context( errors::ApiErrorResponse::MandateValidationFailed { - reason: "Expected one out of mandate_id and mandate_data but got both".into(), + reason: "Expected one out of recurring_details and mandate_data but got both".into(), }, )? { Some(api::MandateTransactionType::NewMandateTransaction) => { @@ -809,6 +869,23 @@ pub fn validate_mandate( } } +pub fn validate_recurring_details_and_token( + recurring_details: &Option, + payment_token: &Option, +) -> CustomResult<(), errors::ApiErrorResponse> { + utils::when( + recurring_details.is_some() && payment_token.is_some(), + || { + Err(report!(errors::ApiErrorResponse::PreconditionFailed { + message: "Expected one out of recurring_details and payment_token but got both" + .into() + })) + }, + )?; + + Ok(()) +} + fn validate_new_mandate_request( req: api::MandateValidationFields, is_confirm_operation: bool, @@ -940,7 +1017,8 @@ pub fn create_complete_authorize_url( } fn validate_recurring_mandate(req: api::MandateValidationFields) -> RouterResult<()> { - req.mandate_id.check_value_present("mandate_id")?; + req.recurring_details + .check_value_present("recurring_details")?; req.customer_id.check_value_present("customer_id")?; @@ -1950,7 +2028,8 @@ pub(crate) fn validate_payment_method_fields_present( utils::when( req.payment_method.is_some() && req.payment_method_data.is_none() - && req.payment_token.is_none(), + && req.payment_token.is_none() + && req.recurring_details.is_none(), || { Err(errors::ApiErrorResponse::MissingRequiredField { field_name: "payment_method_data", diff --git a/crates/router/src/core/payments/operations/payment_approve.rs b/crates/router/src/core/payments/operations/payment_approve.rs index 65b856364cc..a2132bed8c1 100644 --- a/crates/router/src/core/payments/operations/payment_approve.rs +++ b/crates/router/src/core/payments/operations/payment_approve.rs @@ -178,6 +178,7 @@ impl authorizations: vec![], frm_metadata: None, authentication: None, + recurring_details: None, }; let get_trackers_response = operations::GetTrackerResponse { diff --git a/crates/router/src/core/payments/operations/payment_cancel.rs b/crates/router/src/core/payments/operations/payment_cancel.rs index b25c0e2b909..ab5feb5d9b5 100644 --- a/crates/router/src/core/payments/operations/payment_cancel.rs +++ b/crates/router/src/core/payments/operations/payment_cancel.rs @@ -187,6 +187,7 @@ impl authorizations: vec![], frm_metadata: None, authentication: None, + recurring_details: None, }; let get_trackers_response = operations::GetTrackerResponse { diff --git a/crates/router/src/core/payments/operations/payment_capture.rs b/crates/router/src/core/payments/operations/payment_capture.rs index 47d339f15be..4445589f42f 100644 --- a/crates/router/src/core/payments/operations/payment_capture.rs +++ b/crates/router/src/core/payments/operations/payment_capture.rs @@ -231,6 +231,7 @@ impl authorizations: vec![], frm_metadata: None, authentication: None, + recurring_details: None, }; let get_trackers_response = operations::GetTrackerResponse { diff --git a/crates/router/src/core/payments/operations/payment_complete_authorize.rs b/crates/router/src/core/payments/operations/payment_complete_authorize.rs index 8a773904ea3..b788ebc95f7 100644 --- a/crates/router/src/core/payments/operations/payment_complete_authorize.rs +++ b/crates/router/src/core/payments/operations/payment_complete_authorize.rs @@ -10,6 +10,7 @@ use super::{BoxedOperation, Domain, GetTracker, Operation, UpdateTracker, Valida use crate::{ core::{ errors::{self, CustomResult, RouterResult, StorageErrorExt}, + mandate::helpers::MandateGenericData, payment_methods::PaymentMethodRetrieve, payments::{self, helpers, operations, CustomerDetails, PaymentAddress, PaymentData}, utils as core_utils, @@ -71,17 +72,18 @@ impl "confirm", )?; - let ( + let MandateGenericData { token, payment_method, payment_method_type, - setup_mandate, + mandate_data, recurring_mandate_payment_data, mandate_connector, - ) = helpers::get_token_pm_type_mandate_details( + payment_method_info, + } = helpers::get_token_pm_type_mandate_details( state, request, - mandate_type.clone(), + mandate_type.to_owned(), merchant_account, key_store, ) @@ -225,7 +227,7 @@ impl payment_intent.metadata = request.metadata.clone().or(payment_intent.metadata); // The operation merges mandate data from both request and payment_attempt - let setup_mandate = setup_mandate.map(Into::into); + let setup_mandate = mandate_data.map(Into::into); let mandate_details_present = payment_attempt.mandate_details.is_some() || request.mandate_data.is_some(); @@ -270,7 +272,7 @@ impl .payment_method_data .as_ref() .map(|pmd| pmd.payment_method_data.clone()), - payment_method_info: None, + payment_method_info, force_sync: None, refunds: vec![], disputes: vec![], @@ -291,6 +293,7 @@ impl authorizations: vec![], authentication: None, frm_metadata: None, + recurring_details: request.recurring_details.clone(), }; let customer_details = Some(CustomerDetails { @@ -455,6 +458,11 @@ impl ValidateRequest .setup_future_usage .or(payment_intent.setup_future_usage); - let ( + let MandateGenericData { token, payment_method, payment_method_type, - mut setup_mandate, + mandate_data, recurring_mandate_payment_data, mandate_connector, - ) = mandate_details; + payment_method_info, + } = mandate_details; let browser_info = request .browser_info @@ -406,7 +408,7 @@ impl (Some(token_data), payment_method_info) } else { - (None, None) + (None, payment_method_info) }; payment_attempt.payment_method = payment_method.or(payment_attempt.payment_method); @@ -478,7 +480,7 @@ impl .or(payment_attempt.business_sub_label); // The operation merges mandate data from both request and payment_attempt - setup_mandate = setup_mandate.map(|mut sm| { + let setup_mandate = mandate_data.map(|mut sm| { sm.mandate_type = payment_attempt.mandate_details.clone().or(sm.mandate_type); sm.update_mandate_id = payment_attempt .mandate_data @@ -619,6 +621,7 @@ impl authorizations: vec![], frm_metadata: request.frm_metadata.clone(), authentication, + recurring_details: request.recurring_details.clone(), }; let get_trackers_response = operations::GetTrackerResponse { @@ -1199,6 +1202,11 @@ impl ValidateRequest })? }; - let ( + let MandateGenericData { token, payment_method, payment_method_type, - setup_mandate, + mandate_data, recurring_mandate_payment_data, mandate_connector, - ) = helpers::get_token_pm_type_mandate_details( + payment_method_info, + } = helpers::get_token_pm_type_mandate_details( state, request, mandate_type, @@ -291,6 +293,14 @@ impl let mandate_id = request .mandate_id .as_ref() + .or_else(|| { + request.recurring_details + .as_ref() + .and_then(|recurring_details| match recurring_details { + RecurringDetails::MandateId(id) => Some(id), + _ => None, + }) + }) .async_and_then(|mandate_id| async { let mandate = db .find_mandate_by_merchant_id_mandate_id(merchant_id, mandate_id) @@ -359,7 +369,7 @@ impl .transpose()?; // The operation merges mandate data from both request and payment_attempt - let setup_mandate = setup_mandate.map(MandateData::from); + let setup_mandate = mandate_data.map(MandateData::from); let customer_acceptance = request.customer_acceptance.clone().map(From::from); @@ -398,7 +408,7 @@ impl token_data: None, confirm: request.confirm, payment_method_data: payment_method_data_after_card_bin_call, - payment_method_info: None, + payment_method_info, refunds: vec![], disputes: vec![], attempts: None, @@ -419,6 +429,7 @@ impl authorizations: vec![], authentication: None, frm_metadata: request.frm_metadata.clone(), + recurring_details: request.recurring_details.clone(), }; let get_trackers_response = operations::GetTrackerResponse { @@ -676,6 +687,11 @@ impl ValidateRequest authorizations: vec![], authentication: None, frm_metadata: None, + recurring_details: None, }; let get_trackers_response = operations::GetTrackerResponse { diff --git a/crates/router/src/core/payments/operations/payment_session.rs b/crates/router/src/core/payments/operations/payment_session.rs index 805b5fb3630..25b419e3222 100644 --- a/crates/router/src/core/payments/operations/payment_session.rs +++ b/crates/router/src/core/payments/operations/payment_session.rs @@ -199,6 +199,7 @@ impl authorizations: vec![], authentication: None, frm_metadata: None, + recurring_details: None, }; let get_trackers_response = operations::GetTrackerResponse { diff --git a/crates/router/src/core/payments/operations/payment_start.rs b/crates/router/src/core/payments/operations/payment_start.rs index 520336be0e1..465a2e5818d 100644 --- a/crates/router/src/core/payments/operations/payment_start.rs +++ b/crates/router/src/core/payments/operations/payment_start.rs @@ -186,6 +186,7 @@ impl authorizations: vec![], authentication: None, frm_metadata: None, + recurring_details: None, }; let get_trackers_response = operations::GetTrackerResponse { diff --git a/crates/router/src/core/payments/operations/payment_status.rs b/crates/router/src/core/payments/operations/payment_status.rs index 101d997db21..4d616146908 100644 --- a/crates/router/src/core/payments/operations/payment_status.rs +++ b/crates/router/src/core/payments/operations/payment_status.rs @@ -462,6 +462,7 @@ async fn get_tracker_for_sync< authorizations, authentication, frm_metadata: None, + recurring_details: None, }; let get_trackers_response = operations::GetTrackerResponse { diff --git a/crates/router/src/core/payments/operations/payment_update.rs b/crates/router/src/core/payments/operations/payment_update.rs index 2a0b99bc54b..684f7c4b698 100644 --- a/crates/router/src/core/payments/operations/payment_update.rs +++ b/crates/router/src/core/payments/operations/payment_update.rs @@ -1,6 +1,8 @@ use std::marker::PhantomData; -use api_models::{enums::FrmSuggestion, payments::RequestSurchargeDetails}; +use api_models::{ + enums::FrmSuggestion, mandates::RecurringDetails, payments::RequestSurchargeDetails, +}; use async_trait::async_trait; use common_utils::ext_traits::{AsyncExt, Encode, ValueExt}; use error_stack::{report, IntoReport, ResultExt}; @@ -11,6 +13,7 @@ use super::{BoxedOperation, Domain, GetTracker, Operation, UpdateTracker, Valida use crate::{ core::{ errors::{self, CustomResult, RouterResult, StorageErrorExt}, + mandate::helpers::MandateGenericData, payment_methods::PaymentMethodRetrieve, payments::{self, helpers, operations, CustomerDetails, PaymentAddress, PaymentData}, utils as core_utils, @@ -94,17 +97,19 @@ impl )?; helpers::authenticate_client_secret(request.client_secret.as_ref(), &payment_intent)?; - let ( + + let MandateGenericData { token, payment_method, payment_method_type, - setup_mandate, + mandate_data, recurring_mandate_payment_data, mandate_connector, - ) = helpers::get_token_pm_type_mandate_details( + payment_method_info, + } = helpers::get_token_pm_type_mandate_details( state, request, - mandate_type.clone(), + mandate_type.to_owned(), merchant_account, key_store, ) @@ -263,6 +268,14 @@ impl let mandate_id = request .mandate_id .as_ref() + .or_else(|| { + request.recurring_details + .as_ref() + .and_then(|recurring_details| match recurring_details { + RecurringDetails::MandateId(id) => Some(id), + _ => None, + }) + }) .async_and_then(|mandate_id| async { let mandate = db .find_mandate_by_merchant_id_mandate_id(merchant_id, mandate_id) @@ -357,7 +370,7 @@ impl .transpose()?; // The operation merges mandate data from both request and payment_attempt - let setup_mandate = setup_mandate.map(Into::into); + let setup_mandate = mandate_data.map(Into::into); let mandate_details_present = payment_attempt.mandate_details.is_some() || request.mandate_data.is_some(); helpers::validate_mandate_data_and_future_usage( @@ -405,7 +418,7 @@ impl .payment_method_data .as_ref() .map(|pmd| pmd.payment_method_data.clone()), - payment_method_info: None, + payment_method_info, force_sync: None, refunds: vec![], disputes: vec![], @@ -426,6 +439,7 @@ impl authorizations: vec![], authentication: None, frm_metadata: request.frm_metadata.clone(), + recurring_details: request.recurring_details.clone(), }; let get_trackers_response = operations::GetTrackerResponse { @@ -737,6 +751,11 @@ impl ValidateRequest authorizations: vec![], authentication: None, frm_metadata: None, + recurring_details: None, }; let get_trackers_response = operations::GetTrackerResponse { diff --git a/crates/router/src/types/api/payments.rs b/crates/router/src/types/api/payments.rs index 8e13f6c9935..d465300dd61 100644 --- a/crates/router/src/types/api/payments.rs +++ b/crates/router/src/types/api/payments.rs @@ -115,10 +115,11 @@ impl MandateValidationFieldsExt for MandateValidationFields { fn validate_and_get_mandate_type( &self, ) -> errors::CustomResult, errors::ValidationError> { - match (&self.mandate_data, &self.mandate_id) { + match (&self.mandate_data, &self.recurring_details) { (None, None) => Ok(None), (Some(_), Some(_)) => Err(errors::ValidationError::InvalidValue { - message: "Expected one out of mandate_id and mandate_data but got both".to_string(), + message: "Expected one out of recurring_details and mandate_data but got both" + .to_string(), }) .into_report(), (_, Some(_)) => Ok(Some(MandateTransactionType::RecurringMandateTransaction)), diff --git a/openapi/openapi_spec.json b/openapi/openapi_spec.json index 2005f9c11e0..fa9c7435632 100644 --- a/openapi/openapi_spec.json +++ b/openapi/openapi_spec.json @@ -13334,6 +13334,14 @@ "description": "Whether to perform external authentication (if applicable)", "example": true, "nullable": true + }, + "recurring_details": { + "allOf": [ + { + "$ref": "#/components/schemas/RecurringDetails" + } + ], + "nullable": true } } }, @@ -13726,6 +13734,14 @@ "description": "Whether to perform external authentication (if applicable)", "example": true, "nullable": true + }, + "recurring_details": { + "allOf": [ + { + "$ref": "#/components/schemas/RecurringDetails" + } + ], + "nullable": true } } }, @@ -14220,6 +14236,14 @@ "description": "Whether to perform external authentication (if applicable)", "example": true, "nullable": true + }, + "recurring_details": { + "allOf": [ + { + "$ref": "#/components/schemas/RecurringDetails" + } + ], + "nullable": true } } }, @@ -15220,6 +15244,14 @@ "description": "Whether to perform external authentication (if applicable)", "example": true, "nullable": true + }, + "recurring_details": { + "allOf": [ + { + "$ref": "#/components/schemas/RecurringDetails" + } + ], + "nullable": true } } }, @@ -16129,6 +16161,49 @@ "disabled" ] }, + "RecurringDetails": { + "oneOf": [ + { + "type": "object", + "required": [ + "type", + "data" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "mandate_id" + ] + }, + "data": { + "type": "string" + } + } + }, + { + "type": "object", + "required": [ + "type", + "data" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "payment_method_id" + ] + }, + "data": { + "type": "string" + } + } + } + ], + "discriminator": { + "propertyName": "type" + } + }, "RedirectResponse": { "type": "object", "properties": { From cb2000b08856ceb64201d0aff7d81665524665b2 Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 1 Apr 2024 00:06:07 +0000 Subject: [PATCH 17/20] chore(version): 2024.04.01.0 --- CHANGELOG.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f41ba2b094d..3ead87751c4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,21 @@ All notable changes to HyperSwitch will be documented here. - - - +## 2024.04.01.0 + +### Features + +- **mandates:** Allow off-session payments using `payment_method_id` ([#4132](https://github.com/juspay/hyperswitch/pull/4132)) ([`7b337ac`](https://github.com/juspay/hyperswitch/commit/7b337ac39d72f90dd0ebe58133218896ff279313)) +- **payment_method:** API to list countries and currencies supported by a country and payment method type ([#4126](https://github.com/juspay/hyperswitch/pull/4126)) ([`74cd4a7`](https://github.com/juspay/hyperswitch/commit/74cd4a79526eb1a2dead87855e6a39248ec5ccb7)) + +### Miscellaneous Tasks + +- **config:** Add billwerk base URL in deployment configs ([#4243](https://github.com/juspay/hyperswitch/pull/4243)) ([`e8289f0`](https://github.com/juspay/hyperswitch/commit/e8289f061d4735478cb1521de50f696d2412ad33)) + +**Full Changelog:** [`2024.03.28.0...2024.04.01.0`](https://github.com/juspay/hyperswitch/compare/2024.03.28.0...2024.04.01.0) + +- - - + ## 2024.03.28.0 ### Features From ea730d4ffc712cdf264492db109836fcde9b2b03 Mon Sep 17 00:00:00 2001 From: Sanchith Hegde <22217505+SanchithHegde@users.noreply.github.com> Date: Mon, 1 Apr 2024 12:31:17 +0530 Subject: [PATCH 18/20] build(deps): bump `error-stack` from version `0.3.1` to `0.4.1` (#4188) --- Cargo.lock | 82 ++--- connector-template/mod.rs | 17 +- crates/analytics/Cargo.toml | 2 +- crates/analytics/src/api_event/core.rs | 5 +- crates/analytics/src/clickhouse.rs | 139 +++----- crates/analytics/src/connector_events/core.rs | 3 +- crates/analytics/src/disputes/core.rs | 3 +- crates/analytics/src/lambda_utils.rs | 5 +- crates/analytics/src/lib.rs | 6 +- .../src/outgoing_webhook_event/core.rs | 3 +- crates/analytics/src/payments/core.rs | 3 +- crates/analytics/src/query.rs | 7 +- crates/analytics/src/refunds/core.rs | 3 +- crates/analytics/src/sdk_events/core.rs | 5 +- crates/analytics/src/sqlx.rs | 8 +- crates/api_models/Cargo.toml | 2 +- crates/api_models/src/routing.rs | 13 +- crates/cards/Cargo.toml | 2 +- crates/common_utils/Cargo.toml | 2 +- crates/common_utils/src/crypto.rs | 25 +- crates/common_utils/src/ext_traits.rs | 17 +- crates/common_utils/src/pii.rs | 6 +- crates/common_utils/src/types.rs | 17 +- crates/data_models/Cargo.toml | 2 +- crates/data_models/src/mandates.rs | 3 +- crates/diesel_models/Cargo.toml | 2 +- crates/diesel_models/src/kv.rs | 3 +- crates/diesel_models/src/query/events.rs | 6 +- crates/diesel_models/src/query/generics.rs | 33 +- .../src/query/payment_attempt.rs | 48 +-- .../diesel_models/src/query/payment_method.rs | 3 +- .../diesel_models/src/query/payout_attempt.rs | 5 +- .../src/query/routing_algorithm.rs | 9 +- crates/diesel_models/src/query/user.rs | 11 +- .../src/query/user/sample_data.rs | 8 +- crates/drainer/Cargo.toml | 2 +- crates/drainer/src/lib.rs | 11 +- crates/drainer/src/stream.rs | 10 +- crates/drainer/src/types.rs | 3 +- crates/drainer/src/utils.rs | 15 +- crates/external_services/Cargo.toml | 2 +- crates/external_services/src/aws_kms/core.rs | 13 +- crates/external_services/src/email/ses.rs | 6 +- .../src/file_storage/file_system.rs | 20 +- .../src/no_encryption/implementers.rs | 3 +- crates/pm_auth/Cargo.toml | 2 +- crates/redis_interface/Cargo.toml | 2 +- crates/redis_interface/src/commands.rs | 41 +-- crates/redis_interface/src/lib.rs | 7 +- crates/redis_interface/src/types.rs | 7 +- crates/router/Cargo.toml | 2 +- .../stripe/payment_intents/types.rs | 15 +- .../stripe/setup_intents/types.rs | 5 +- .../src/compatibility/stripe/webhooks.rs | 3 +- crates/router/src/connection.rs | 4 +- crates/router/src/connector/aci.rs | 9 +- crates/router/src/connector/adyen.rs | 9 +- .../src/connector/adyen/transformers.rs | 4 +- crates/router/src/connector/airwallex.rs | 50 ++- .../src/connector/airwallex/transformers.rs | 3 +- .../router/src/connector/authorizedotnet.rs | 13 +- .../connector/authorizedotnet/transformers.rs | 3 +- crates/router/src/connector/bambora.rs | 11 +- .../src/connector/bambora/transformers.rs | 3 +- crates/router/src/connector/bankofamerica.rs | 14 +- .../connector/bankofamerica/transformers.rs | 3 +- crates/router/src/connector/billwerk.rs | 8 +- crates/router/src/connector/bluesnap.rs | 18 +- .../src/connector/bluesnap/transformers.rs | 11 +- crates/router/src/connector/boku.rs | 15 +- crates/router/src/connector/braintree.rs | 20 +- .../braintree_graphql_transformers.rs | 15 +- crates/router/src/connector/cashtocode.rs | 4 +- .../src/connector/cashtocode/transformers.rs | 5 +- crates/router/src/connector/checkout.rs | 19 +- .../src/connector/checkout/transformers.rs | 3 +- crates/router/src/connector/coinbase.rs | 4 +- crates/router/src/connector/cryptopay.rs | 5 +- crates/router/src/connector/cybersource.rs | 13 +- .../src/connector/cybersource/transformers.rs | 3 +- crates/router/src/connector/dlocal.rs | 32 +- crates/router/src/connector/dummyconnector.rs | 6 +- crates/router/src/connector/fiserv.rs | 39 +-- crates/router/src/connector/forte.rs | 9 +- crates/router/src/connector/globalpay.rs | 38 +-- .../src/connector/globalpay/transformers.rs | 11 +- crates/router/src/connector/globepay.rs | 8 +- crates/router/src/connector/gocardless.rs | 10 +- crates/router/src/connector/helcim.rs | 8 +- .../src/connector/helcim/transformers.rs | 19 +- crates/router/src/connector/iatapay.rs | 3 +- crates/router/src/connector/klarna.rs | 9 +- crates/router/src/connector/mollie.rs | 17 +- .../src/connector/mollie/transformers.rs | 17 +- crates/router/src/connector/multisafepay.rs | 24 +- crates/router/src/connector/nexinets.rs | 6 +- .../src/connector/nexinets/transformers.rs | 4 +- crates/router/src/connector/nmi.rs | 30 +- .../router/src/connector/nmi/transformers.rs | 19 +- crates/router/src/connector/noon.rs | 3 +- .../router/src/connector/noon/transformers.rs | 10 +- crates/router/src/connector/nuvei.rs | 13 +- .../src/connector/nuvei/transformers.rs | 5 +- crates/router/src/connector/opayo.rs | 8 +- crates/router/src/connector/opennode.rs | 8 +- crates/router/src/connector/payeezy.rs | 8 +- crates/router/src/connector/payme.rs | 10 +- .../src/connector/payme/transformers.rs | 3 +- crates/router/src/connector/paypal.rs | 3 +- .../src/connector/paypal/transformers.rs | 5 +- crates/router/src/connector/payu.rs | 39 +-- .../router/src/connector/payu/transformers.rs | 3 +- crates/router/src/connector/placetopay.rs | 8 +- .../src/connector/placetopay/transformers.rs | 9 +- crates/router/src/connector/powertranz.rs | 8 +- .../src/connector/powertranz/transformers.rs | 5 +- crates/router/src/connector/prophetpay.rs | 8 +- .../src/connector/prophetpay/transformers.rs | 8 +- crates/router/src/connector/rapyd.rs | 31 +- .../src/connector/rapyd/transformers.rs | 4 +- crates/router/src/connector/riskified.rs | 8 +- crates/router/src/connector/shift4.rs | 22 +- .../src/connector/shift4/transformers.rs | 3 +- crates/router/src/connector/signifyd.rs | 8 +- crates/router/src/connector/square.rs | 4 +- .../src/connector/square/transformers.rs | 4 +- crates/router/src/connector/stax.rs | 4 +- .../router/src/connector/stax/transformers.rs | 6 +- crates/router/src/connector/stripe.rs | 22 +- .../src/connector/stripe/transformers.rs | 10 +- crates/router/src/connector/threedsecureio.rs | 8 +- .../connector/threedsecureio/transformers.rs | 9 +- crates/router/src/connector/trustpay.rs | 3 +- crates/router/src/connector/tsys.rs | 8 +- crates/router/src/connector/utils.rs | 25 +- crates/router/src/connector/volt.rs | 3 +- crates/router/src/connector/wise.rs | 8 +- crates/router/src/connector/worldline.rs | 41 +-- crates/router/src/connector/worldpay.rs | 11 +- crates/router/src/connector/zen.rs | 7 +- crates/router/src/core/admin.rs | 42 +-- crates/router/src/core/api_keys.rs | 11 +- crates/router/src/core/api_locking.rs | 19 +- crates/router/src/core/authentication.rs | 4 +- crates/router/src/core/blocklist/utils.rs | 18 +- crates/router/src/core/conditional_config.rs | 3 +- .../src/core/connector_onboarding/paypal.rs | 5 +- crates/router/src/core/customers.rs | 6 +- crates/router/src/core/disputes.rs | 3 +- crates/router/src/core/files.rs | 4 +- crates/router/src/core/files/helpers.rs | 5 +- .../fraud_check/operation/fraud_check_post.rs | 2 - crates/router/src/core/gsm.rs | 3 +- crates/router/src/core/mandate.rs | 16 +- crates/router/src/core/payment_link.rs | 16 +- .../router/src/core/payment_methods/cards.rs | 26 +- .../surcharge_decision_configs.rs | 13 +- .../router/src/core/payment_methods/vault.rs | 22 +- crates/router/src/core/payments.rs | 20 +- .../router/src/core/payments/access_token.rs | 3 +- .../src/core/payments/conditional_configs.rs | 8 +- .../src/core/payments/flows/session_flow.rs | 4 +- .../core/payments/flows/setup_mandate_flow.rs | 7 +- crates/router/src/core/payments/helpers.rs | 315 +++++++++--------- .../payments/operations/payment_approve.rs | 10 +- .../operations/payment_complete_authorize.rs | 6 +- .../payments/operations/payment_confirm.rs | 8 +- .../payments/operations/payment_response.rs | 4 +- .../payments/operations/payment_update.rs | 6 +- .../payments_incremental_authorization.rs | 3 +- crates/router/src/core/payments/retry.rs | 13 +- crates/router/src/core/payments/routing.rs | 26 +- .../router/src/core/payments/transformers.rs | 4 +- crates/router/src/core/payments/types.rs | 4 +- crates/router/src/core/payouts.rs | 6 +- crates/router/src/core/payouts/helpers.rs | 5 +- crates/router/src/core/payouts/retry.rs | 16 +- crates/router/src/core/pm_auth.rs | 11 +- crates/router/src/core/pm_auth/helpers.rs | 3 +- crates/router/src/core/refunds.rs | 7 +- crates/router/src/core/refunds/validator.rs | 6 +- crates/router/src/core/routing.rs | 25 +- .../src/core/surcharge_decision_config.rs | 3 +- crates/router/src/core/user.rs | 18 +- .../src/core/user/dashboard_metadata.rs | 4 +- crates/router/src/core/user_role.rs | 18 +- crates/router/src/core/user_role/role.rs | 6 +- crates/router/src/core/utils.rs | 12 +- crates/router/src/core/verify_connector.rs | 14 +- crates/router/src/core/webhooks.rs | 51 +-- crates/router/src/db/address.rs | 51 +-- crates/router/src/db/api_keys.rs | 26 +- crates/router/src/db/authentication.rs | 11 +- crates/router/src/db/authorization.rs | 11 +- crates/router/src/db/blocklist.rs | 17 +- crates/router/src/db/blocklist_fingerprint.rs | 8 +- crates/router/src/db/blocklist_lookup.rs | 11 +- crates/router/src/db/business_profile.rs | 20 +- crates/router/src/db/capture.rs | 22 +- crates/router/src/db/cards_info.rs | 5 +- crates/router/src/db/configs.rs | 31 +- crates/router/src/db/customers.rs | 20 +- crates/router/src/db/dashboard_metadata.rs | 25 +- crates/router/src/db/dispute.rs | 25 +- crates/router/src/db/events.rs | 29 +- crates/router/src/db/file.rs | 15 +- crates/router/src/db/fraud_check.rs | 15 +- crates/router/src/db/gsm.rs | 18 +- crates/router/src/db/locker_mock_up.rs | 17 +- crates/router/src/db/mandate.rs | 26 +- crates/router/src/db/merchant_account.rs | 35 +- .../src/db/merchant_connector_account.rs | 35 +- crates/router/src/db/merchant_key_store.rs | 14 +- crates/router/src/db/organization.rs | 11 +- crates/router/src/db/payment_link.rs | 11 +- crates/router/src/db/payment_method.rs | 44 +-- crates/router/src/db/refund.rs | 78 ++--- crates/router/src/db/reverse_lookup.rs | 22 +- crates/router/src/db/role.rs | 27 +- crates/router/src/db/routing_algorithm.rs | 23 +- crates/router/src/db/user.rs | 29 +- crates/router/src/db/user_role.rs | 32 +- crates/router/src/routes/disputes/utils.rs | 10 +- .../src/routes/dummy_connector/utils.rs | 4 +- .../router/src/routes/files/transformers.rs | 11 +- crates/router/src/routes/payments.rs | 5 +- crates/router/src/routes/recon.rs | 8 +- crates/router/src/services.rs | 3 +- crates/router/src/services/api.rs | 19 +- crates/router/src/services/api/client.rs | 12 +- crates/router/src/services/api/request.rs | 4 +- crates/router/src/services/authentication.rs | 6 +- .../src/services/authentication/blacklist.rs | 7 +- crates/router/src/services/authorization.rs | 9 +- crates/router/src/services/encryption.rs | 12 +- crates/router/src/services/jwt.rs | 4 +- crates/router/src/services/kafka.rs | 7 +- crates/router/src/types.rs | 3 +- crates/router/src/types/api.rs | 4 +- crates/router/src/types/api/authentication.rs | 3 +- .../types/api/connector_onboarding/paypal.rs | 4 +- crates/router/src/types/api/fraud_check.rs | 3 +- crates/router/src/types/api/payments.rs | 7 +- .../router/src/types/api/verify_connector.rs | 10 +- .../src/types/api/verify_connector/stripe.rs | 6 +- crates/router/src/types/domain/address.rs | 2 +- crates/router/src/types/domain/customer.rs | 2 +- crates/router/src/types/domain/event.rs | 2 +- .../src/types/domain/merchant_account.rs | 2 +- crates/router/src/types/domain/types.rs | 9 +- crates/router/src/types/domain/user.rs | 12 +- crates/router/src/types/pm_auth.rs | 3 +- crates/router/src/types/storage/dispute.rs | 3 +- crates/router/src/types/storage/mandate.rs | 3 +- .../router/src/types/storage/payment_link.rs | 3 +- crates/router/src/types/storage/refund.rs | 7 +- crates/router/src/types/transformers.rs | 14 +- crates/router/src/utils.rs | 27 +- .../src/utils/connector_onboarding/paypal.rs | 11 +- crates/router/src/utils/currency.rs | 19 +- crates/router/src/utils/ext_traits.rs | 3 +- crates/router/src/utils/user.rs | 4 +- .../src/utils/user/dashboard_metadata.rs | 16 +- crates/router/src/utils/user/password.rs | 9 +- crates/router/src/utils/user/sample_data.rs | 5 +- crates/router/src/utils/user_role.rs | 12 +- crates/router/src/utils/verify_connector.rs | 5 +- crates/router_env/Cargo.toml | 2 +- crates/scheduler/Cargo.toml | 2 +- crates/scheduler/src/consumer.rs | 5 +- crates/scheduler/src/consumer/types/batch.rs | 12 +- crates/scheduler/src/db/process_tracker.rs | 20 +- crates/scheduler/src/producer.rs | 5 +- crates/storage_impl/Cargo.toml | 2 +- crates/storage_impl/src/connection.rs | 4 +- crates/storage_impl/src/database/store.rs | 3 +- crates/storage_impl/src/lookup.rs | 7 +- .../src/mock_db/payment_intent.rs | 8 +- .../src/payments/payment_attempt.rs | 8 +- .../src/payments/payment_intent.rs | 12 +- .../src/payouts/payout_attempt.rs | 6 +- crates/storage_impl/src/payouts/payouts.rs | 10 +- crates/storage_impl/src/redis.rs | 3 +- crates/storage_impl/src/redis/kv_store.rs | 8 +- crates/storage_impl/src/redis/pub_sub.rs | 7 +- crates/storage_impl/src/utils.rs | 4 +- 286 files changed, 1361 insertions(+), 2397 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4d8d1e8c6a3..8f571b3b922 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -80,7 +80,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e01ed3140b2f8d422c68afa1ed2e85d996ea619c988ac834d255db32138655cb" dependencies = [ "quote", - "syn 2.0.53", + "syn 2.0.55", ] [[package]] @@ -118,7 +118,7 @@ dependencies = [ "parse-size", "proc-macro2", "quote", - "syn 2.0.53", + "syn 2.0.55", ] [[package]] @@ -255,7 +255,7 @@ dependencies = [ "actix-router", "proc-macro2", "quote", - "syn 2.0.53", + "syn 2.0.55", ] [[package]] @@ -394,9 +394,9 @@ checksum = "41ed9a86bf92ae6580e0a31281f65a1b1d867c0cc68d5346e2ae128dddfa6a7d" [[package]] name = "anyhow" -version = "1.0.75" +version = "1.0.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" +checksum = "0952808a6c2afd1aa8947271f3a60f1a6763c7b912d210184c5149b5cf147247" [[package]] name = "api_models" @@ -566,7 +566,7 @@ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" dependencies = [ "proc-macro2", "quote", - "syn 2.0.53", + "syn 2.0.55", ] [[package]] @@ -577,7 +577,7 @@ checksum = "c980ee35e870bd1a4d2c8294d4c04d0499e67bca1e4b5cefcc693c2fa00caea9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.53", + "syn 2.0.55", ] [[package]] @@ -1600,7 +1600,7 @@ dependencies = [ "proc-macro-crate 2.0.0", "proc-macro2", "quote", - "syn 2.0.53", + "syn 2.0.55", "syn_derive", ] @@ -1922,7 +1922,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.53", + "syn 2.0.55", ] [[package]] @@ -2355,7 +2355,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.53", + "syn 2.0.55", ] [[package]] @@ -2377,7 +2377,7 @@ checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5" dependencies = [ "darling_core 0.20.3", "quote", - "syn 2.0.53", + "syn 2.0.55", ] [[package]] @@ -2545,7 +2545,7 @@ dependencies = [ "diesel_table_macro_syntax", "proc-macro2", "quote", - "syn 2.0.53", + "syn 2.0.55", ] [[package]] @@ -2575,7 +2575,7 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc5557efc453706fed5e4fa85006fe9817c224c3f480a34c7e5959fd700921c5" dependencies = [ - "syn 2.0.53", + "syn 2.0.55", ] [[package]] @@ -2632,7 +2632,7 @@ checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.53", + "syn 2.0.55", ] [[package]] @@ -2733,9 +2733,9 @@ dependencies = [ [[package]] name = "error-stack" -version = "0.3.1" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f00447f331c7f726db5b8532ebc9163519eed03c6d7c8b73c90b3ff5646ac85" +checksum = "27a72baa257b5e0e2de241967bc5ee8f855d6072351042688621081d66b2a76b" dependencies = [ "anyhow", "rustc_version 0.4.0", @@ -2981,7 +2981,7 @@ checksum = "b0fa992f1656e1707946bbba340ad244f0814009ef8c0118eb7b658395f19a2e" dependencies = [ "frunk_proc_macro_helpers", "quote", - "syn 2.0.53", + "syn 2.0.55", ] [[package]] @@ -2993,7 +2993,7 @@ dependencies = [ "frunk_core", "proc-macro2", "quote", - "syn 2.0.53", + "syn 2.0.55", ] [[package]] @@ -3005,7 +3005,7 @@ dependencies = [ "frunk_core", "frunk_proc_macro_helpers", "quote", - "syn 2.0.53", + "syn 2.0.55", ] [[package]] @@ -3118,7 +3118,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.53", + "syn 2.0.55", ] [[package]] @@ -4480,7 +4480,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.53", + "syn 2.0.55", ] [[package]] @@ -4766,7 +4766,7 @@ dependencies = [ "pest_meta", "proc-macro2", "quote", - "syn 2.0.53", + "syn 2.0.55", ] [[package]] @@ -4856,7 +4856,7 @@ checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" dependencies = [ "proc-macro2", "quote", - "syn 2.0.53", + "syn 2.0.55", ] [[package]] @@ -5683,7 +5683,7 @@ dependencies = [ "serde", "serde_json", "strum 0.24.1", - "syn 2.0.53", + "syn 2.0.55", ] [[package]] @@ -6077,7 +6077,7 @@ checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.53", + "syn 2.0.55", ] [[package]] @@ -6141,7 +6141,7 @@ checksum = "8725e1dfadb3a50f7e5ce0b1a540466f6ed3fe7a0fca2ac2b8b831d31316bd00" dependencies = [ "proc-macro2", "quote", - "syn 2.0.53", + "syn 2.0.55", ] [[package]] @@ -6191,7 +6191,7 @@ dependencies = [ "darling 0.20.3", "proc-macro2", "quote", - "syn 2.0.53", + "syn 2.0.55", ] [[package]] @@ -6216,7 +6216,7 @@ checksum = "91d129178576168c589c9ec973feedf7d3126c01ac2bf08795109aa35b69fb8f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.53", + "syn 2.0.55", ] [[package]] @@ -6604,7 +6604,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.53", + "syn 2.0.55", ] [[package]] @@ -6626,9 +6626,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.53" +version = "2.0.55" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7383cd0e49fff4b6b90ca5670bfd3e9d6a733b3f90c686605aa7eec8c4996032" +checksum = "002a1b3dbf967edfafc32655d0f377ab0bb7b994aa1d32c8cc7e9b8bf3ebb8f0" dependencies = [ "proc-macro2", "quote", @@ -6644,7 +6644,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.53", + "syn 2.0.55", ] [[package]] @@ -6752,7 +6752,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.53", + "syn 2.0.55", ] [[package]] @@ -6764,7 +6764,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.53", + "syn 2.0.55", "test-case-core", ] @@ -6844,7 +6844,7 @@ checksum = "10712f02019e9288794769fba95cd6847df9874d49d871d062172f9dd41bc4cc" dependencies = [ "proc-macro2", "quote", - "syn 2.0.53", + "syn 2.0.55", ] [[package]] @@ -7034,7 +7034,7 @@ checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.53", + "syn 2.0.55", ] [[package]] @@ -7364,7 +7364,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.53", + "syn 2.0.55", ] [[package]] @@ -7635,7 +7635,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.53", + "syn 2.0.55", ] [[package]] @@ -7793,7 +7793,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.53", + "syn 2.0.55", "wasm-bindgen-shared", ] @@ -7827,7 +7827,7 @@ checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.53", + "syn 2.0.55", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -8201,7 +8201,7 @@ checksum = "b3c129550b3e6de3fd0ba67ba5c81818f9805e58b8d7fee80a3a59d2c9fc601a" dependencies = [ "proc-macro2", "quote", - "syn 2.0.53", + "syn 2.0.55", ] [[package]] diff --git a/connector-template/mod.rs b/connector-template/mod.rs index 987f6a8742f..760e1528cfa 100644 --- a/connector-template/mod.rs +++ b/connector-template/mod.rs @@ -1,7 +1,7 @@ pub mod transformers; use std::fmt::Debug; -use error_stack::{ResultExt, IntoReport}; +use error_stack::{report, ResultExt}; use masking::ExposeInterface; use crate::{ @@ -20,7 +20,6 @@ use crate::{ } }; - use transformers as {{project-name | downcase}}; #[derive(Debug, Clone)] @@ -74,8 +73,8 @@ impl ConnectorCommon for {{project-name | downcase | pascal_case}} { fn get_currency_unit(&self) -> api::CurrencyUnit { todo!() - // TODO! Check connector documentation, on which unit they are processing the currency. - // If the connector accepts amount in lower unit ( i.e cents for USD) then return api::CurrencyUnit::Minor, + // TODO! Check connector documentation, on which unit they are processing the currency. + // If the connector accepts amount in lower unit ( i.e cents for USD) then return api::CurrencyUnit::Minor, // if connector accepts amount in base unit (i.e dollars for USD) then return api::CurrencyUnit::Base } @@ -117,7 +116,7 @@ impl ConnectorCommon for {{project-name | downcase | pascal_case}} { } } -impl ConnectorValidation for {{project-name | downcase | pascal_case}} +impl ConnectorValidation for {{project-name | downcase | pascal_case}} { //TODO: implement functions when support enabled } @@ -274,7 +273,7 @@ impl http_code: res.status_code, }) } - + fn get_error_response( &self, res: Response, @@ -492,20 +491,20 @@ impl api::IncomingWebhook for {{project-name | downcase | pascal_case}} { &self, _request: &api::IncomingWebhookRequestDetails<'_>, ) -> CustomResult { - Err(errors::ConnectorError::WebhooksNotImplemented).into_report() + Err(report!(errors::ConnectorError::WebhooksNotImplemented)) } fn get_webhook_event_type( &self, _request: &api::IncomingWebhookRequestDetails<'_>, ) -> CustomResult { - Err(errors::ConnectorError::WebhooksNotImplemented).into_report() + Err(report!(errors::ConnectorError::WebhooksNotImplemented)) } fn get_webhook_resource_object( &self, _request: &api::IncomingWebhookRequestDetails<'_>, ) -> CustomResult, errors::ConnectorError> { - Err(errors::ConnectorError::WebhooksNotImplemented).into_report() + Err(report!(errors::ConnectorError::WebhooksNotImplemented)) } } diff --git a/crates/analytics/Cargo.toml b/crates/analytics/Cargo.toml index f07e0a94ea5..37b13a39713 100644 --- a/crates/analytics/Cargo.toml +++ b/crates/analytics/Cargo.toml @@ -32,7 +32,7 @@ aws-config = { version = "1.1.6", features = ["behavior-version-latest"] } aws-sdk-lambda = { version = "1.1.4" } aws-smithy-types = { version = "1.1.6" } bigdecimal = { version = "0.3.1", features = ["serde"] } -error-stack = "0.3.1" +error-stack = "0.4.1" futures = "0.3.28" opensearch = { version = "2.2.0", features = ["aws-auth"] } once_cell = "1.18.0" diff --git a/crates/analytics/src/api_event/core.rs b/crates/analytics/src/api_event/core.rs index 81b82c5dce1..7225a6322d4 100644 --- a/crates/analytics/src/api_event/core.rs +++ b/crates/analytics/src/api_event/core.rs @@ -9,7 +9,7 @@ use api_models::analytics::{ GetApiEventMetricRequest, MetricsResponse, }; use common_utils::errors::ReportSwitchExt; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use router_env::{ instrument, logger, tracing::{self, Instrument}, @@ -36,7 +36,6 @@ pub async fn api_events_core( AnalyticsProvider::Sqlx(_) => Err(FiltersError::NotImplemented( "API Events not implemented for SQLX", )) - .into_report() .attach_printable("SQL Analytics is not implemented for API Events"), AnalyticsProvider::Clickhouse(pool) => get_api_event(&merchant_id, req, pool).await, AnalyticsProvider::CombinedSqlx(_sqlx_pool, ckh_pool) @@ -64,7 +63,6 @@ pub async fn get_filters( AnalyticsProvider::Sqlx(_pool) => Err(FiltersError::NotImplemented( "API Events not implemented for SQLX", )) - .into_report() .attach_printable("SQL Analytics is not implemented for API Events"), AnalyticsProvider::Clickhouse(ckh_pool) | AnalyticsProvider::CombinedSqlx(_, ckh_pool) @@ -134,7 +132,6 @@ pub async fn get_api_event_metrics( .join_next() .await .transpose() - .into_report() .change_context(AnalyticsError::UnknownError)? { let data = data?; diff --git a/crates/analytics/src/clickhouse.rs b/crates/analytics/src/clickhouse.rs index 6ebac7c1d92..4d01c20972c 100644 --- a/crates/analytics/src/clickhouse.rs +++ b/crates/analytics/src/clickhouse.rs @@ -2,7 +2,7 @@ use std::sync::Arc; use actix_web::http::StatusCode; use common_utils::errors::ParsingError; -use error_stack::{IntoReport, Report, ResultExt}; +use error_stack::{report, Report, ResultExt}; use router_env::logger; use time::PrimitiveDateTime; @@ -71,7 +71,6 @@ impl ClickhouseClient { .body(format!("{query}\nFORMAT JSON")) .send() .await - .into_report() .change_context(ClickhouseError::ConnectionError)?; logger::debug!(clickhouse_response=?response, query=?query, "Clickhouse response"); @@ -79,16 +78,14 @@ impl ClickhouseClient { response.text().await.map_or_else( |er| { Err(ClickhouseError::ResponseError) - .into_report() .attach_printable_lazy(|| format!("Error: {er:?}")) }, - |t| Err(ClickhouseError::ResponseNotOK(t)).into_report(), + |t| Err(report!(ClickhouseError::ResponseNotOK(t))), ) } else { Ok(response .json::>() .await - .into_report() .change_context(ClickhouseError::ResponseError)? .data) } @@ -149,7 +146,7 @@ where { fn load_row(row: Self::Row) -> common_utils::errors::CustomResult { row.try_into() - .change_context(QueryExecutionError::RowExtractionFailure) + .map_err(|error| error.change_context(QueryExecutionError::RowExtractionFailure)) } } @@ -188,11 +185,9 @@ impl TryInto for serde_json::Value { type Error = Report; fn try_into(self) -> Result { - serde_json::from_value(self) - .into_report() - .change_context(ParsingError::StructParseFailure( - "Failed to parse ApiLogsResult in clickhouse results", - )) + serde_json::from_value(self).change_context(ParsingError::StructParseFailure( + "Failed to parse ApiLogsResult in clickhouse results", + )) } } @@ -200,11 +195,9 @@ impl TryInto for serde_json::Value { type Error = Report; fn try_into(self) -> Result { - serde_json::from_value(self) - .into_report() - .change_context(ParsingError::StructParseFailure( - "Failed to parse SdkEventsResult in clickhouse results", - )) + serde_json::from_value(self).change_context(ParsingError::StructParseFailure( + "Failed to parse SdkEventsResult in clickhouse results", + )) } } @@ -212,11 +205,9 @@ impl TryInto for serde_json::Value { type Error = Report; fn try_into(self) -> Result { - serde_json::from_value(self) - .into_report() - .change_context(ParsingError::StructParseFailure( - "Failed to parse ConnectorEventsResult in clickhouse results", - )) + serde_json::from_value(self).change_context(ParsingError::StructParseFailure( + "Failed to parse ConnectorEventsResult in clickhouse results", + )) } } @@ -224,11 +215,9 @@ impl TryInto for serde_json::Value { type Error = Report; fn try_into(self) -> Result { - serde_json::from_value(self) - .into_report() - .change_context(ParsingError::StructParseFailure( - "Failed to parse PaymentMetricRow in clickhouse results", - )) + serde_json::from_value(self).change_context(ParsingError::StructParseFailure( + "Failed to parse PaymentMetricRow in clickhouse results", + )) } } @@ -236,11 +225,9 @@ impl TryInto for serde_json::Value { type Error = Report; fn try_into(self) -> Result { - serde_json::from_value(self) - .into_report() - .change_context(ParsingError::StructParseFailure( - "Failed to parse PaymentDistributionRow in clickhouse results", - )) + serde_json::from_value(self).change_context(ParsingError::StructParseFailure( + "Failed to parse PaymentDistributionRow in clickhouse results", + )) } } @@ -248,11 +235,9 @@ impl TryInto for serde_json::Value { type Error = Report; fn try_into(self) -> Result { - serde_json::from_value(self) - .into_report() - .change_context(ParsingError::StructParseFailure( - "Failed to parse FilterRow in clickhouse results", - )) + serde_json::from_value(self).change_context(ParsingError::StructParseFailure( + "Failed to parse FilterRow in clickhouse results", + )) } } @@ -260,11 +245,9 @@ impl TryInto for serde_json::Value { type Error = Report; fn try_into(self) -> Result { - serde_json::from_value(self) - .into_report() - .change_context(ParsingError::StructParseFailure( - "Failed to parse RefundMetricRow in clickhouse results", - )) + serde_json::from_value(self).change_context(ParsingError::StructParseFailure( + "Failed to parse RefundMetricRow in clickhouse results", + )) } } @@ -272,22 +255,18 @@ impl TryInto for serde_json::Value { type Error = Report; fn try_into(self) -> Result { - serde_json::from_value(self) - .into_report() - .change_context(ParsingError::StructParseFailure( - "Failed to parse RefundFilterRow in clickhouse results", - )) + serde_json::from_value(self).change_context(ParsingError::StructParseFailure( + "Failed to parse RefundFilterRow in clickhouse results", + )) } } impl TryInto for serde_json::Value { type Error = Report; fn try_into(self) -> Result { - serde_json::from_value(self) - .into_report() - .change_context(ParsingError::StructParseFailure( - "Failed to parse DisputeMetricRow in clickhouse results", - )) + serde_json::from_value(self).change_context(ParsingError::StructParseFailure( + "Failed to parse DisputeMetricRow in clickhouse results", + )) } } @@ -295,11 +274,9 @@ impl TryInto for serde_json::Value { type Error = Report; fn try_into(self) -> Result { - serde_json::from_value(self) - .into_report() - .change_context(ParsingError::StructParseFailure( - "Failed to parse DisputeFilterRow in clickhouse results", - )) + serde_json::from_value(self).change_context(ParsingError::StructParseFailure( + "Failed to parse DisputeFilterRow in clickhouse results", + )) } } @@ -307,11 +284,9 @@ impl TryInto for serde_json::Value { type Error = Report; fn try_into(self) -> Result { - serde_json::from_value(self) - .into_report() - .change_context(ParsingError::StructParseFailure( - "Failed to parse ApiEventMetricRow in clickhouse results", - )) + serde_json::from_value(self).change_context(ParsingError::StructParseFailure( + "Failed to parse ApiEventMetricRow in clickhouse results", + )) } } @@ -319,11 +294,9 @@ impl TryInto for serde_json::Value { type Error = Report; fn try_into(self) -> Result { - serde_json::from_value(self) - .into_report() - .change_context(ParsingError::StructParseFailure( - "Failed to parse LatencyAvg in clickhouse results", - )) + serde_json::from_value(self).change_context(ParsingError::StructParseFailure( + "Failed to parse LatencyAvg in clickhouse results", + )) } } @@ -331,11 +304,9 @@ impl TryInto for serde_json::Value { type Error = Report; fn try_into(self) -> Result { - serde_json::from_value(self) - .into_report() - .change_context(ParsingError::StructParseFailure( - "Failed to parse SdkEventMetricRow in clickhouse results", - )) + serde_json::from_value(self).change_context(ParsingError::StructParseFailure( + "Failed to parse SdkEventMetricRow in clickhouse results", + )) } } @@ -343,11 +314,9 @@ impl TryInto for serde_json::Value { type Error = Report; fn try_into(self) -> Result { - serde_json::from_value(self) - .into_report() - .change_context(ParsingError::StructParseFailure( - "Failed to parse SdkEventFilter in clickhouse results", - )) + serde_json::from_value(self).change_context(ParsingError::StructParseFailure( + "Failed to parse SdkEventFilter in clickhouse results", + )) } } @@ -355,11 +324,9 @@ impl TryInto for serde_json::Value { type Error = Report; fn try_into(self) -> Result { - serde_json::from_value(self) - .into_report() - .change_context(ParsingError::StructParseFailure( - "Failed to parse ApiEventFilter in clickhouse results", - )) + serde_json::from_value(self).change_context(ParsingError::StructParseFailure( + "Failed to parse ApiEventFilter in clickhouse results", + )) } } @@ -367,11 +334,9 @@ impl TryInto for serde_json::Value { type Error = Report; fn try_into(self) -> Result { - serde_json::from_value(self) - .into_report() - .change_context(ParsingError::StructParseFailure( - "Failed to parse OutgoingWebhookLogsResult in clickhouse results", - )) + serde_json::from_value(self).change_context(ParsingError::StructParseFailure( + "Failed to parse OutgoingWebhookLogsResult in clickhouse results", + )) } } @@ -379,11 +344,9 @@ impl ToSql for PrimitiveDateTime { fn to_sql(&self, _table_engine: &TableEngine) -> error_stack::Result { let format = time::format_description::parse("[year]-[month]-[day] [hour]:[minute]:[second]") - .into_report() .change_context(ParsingError::DateTimeParsingError) .attach_printable("Failed to parse format description")?; self.format(&format) - .into_report() .change_context(ParsingError::EncodeError( "failed to encode to clickhouse date-time format", )) diff --git a/crates/analytics/src/connector_events/core.rs b/crates/analytics/src/connector_events/core.rs index 15f841af5f8..a7f5b978428 100644 --- a/crates/analytics/src/connector_events/core.rs +++ b/crates/analytics/src/connector_events/core.rs @@ -1,6 +1,6 @@ use api_models::analytics::connector_events::ConnectorEventsRequest; use common_utils::errors::ReportSwitchExt; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use super::events::{get_connector_events, ConnectorEventsResult}; use crate::{errors::AnalyticsResult, types::FiltersError, AnalyticsProvider}; @@ -14,7 +14,6 @@ pub async fn connector_events_core( AnalyticsProvider::Sqlx(_) => Err(FiltersError::NotImplemented( "Connector Events not implemented for SQLX", )) - .into_report() .attach_printable("SQL Analytics is not implemented for Connector Events"), AnalyticsProvider::Clickhouse(ckh_pool) | AnalyticsProvider::CombinedSqlx(_, ckh_pool) diff --git a/crates/analytics/src/disputes/core.rs b/crates/analytics/src/disputes/core.rs index ae013aa81d1..dfba5fea112 100644 --- a/crates/analytics/src/disputes/core.rs +++ b/crates/analytics/src/disputes/core.rs @@ -8,7 +8,7 @@ use api_models::analytics::{ AnalyticsMetadata, DisputeFilterValue, DisputeFiltersResponse, GetDisputeFilterRequest, GetDisputeMetricRequest, MetricsResponse, }; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use router_env::{ logger, tracing::{self, Instrument}, @@ -67,7 +67,6 @@ pub async fn get_metrics( .join_next() .await .transpose() - .into_report() .change_context(AnalyticsError::UnknownError)? { let data = data?; diff --git a/crates/analytics/src/lambda_utils.rs b/crates/analytics/src/lambda_utils.rs index 4f8320f29b5..9dc90531c7a 100644 --- a/crates/analytics/src/lambda_utils.rs +++ b/crates/analytics/src/lambda_utils.rs @@ -2,7 +2,7 @@ use aws_config::{self, meta::region::RegionProviderChain, Region}; use aws_sdk_lambda::{types::InvocationType::Event, Client}; use aws_smithy_types::Blob; use common_utils::errors::CustomResult; -use error_stack::{IntoReport, ResultExt}; +use error_stack::{report, ResultExt}; use crate::errors::AnalyticsError; @@ -25,10 +25,9 @@ pub async fn invoke_lambda( .payload(Blob::new(json_bytes.to_owned())) .send() .await - .into_report() .map_err(|er| { let er_rep = format!("{er:?}"); - er.attach_printable(er_rep) + report!(er).attach_printable(er_rep) }) .change_context(AnalyticsError::UnknownError) .attach_printable("Lambda invocation failed")?; diff --git a/crates/analytics/src/lib.rs b/crates/analytics/src/lib.rs index a325442047e..3b3cbc9c039 100644 --- a/crates/analytics/src/lib.rs +++ b/crates/analytics/src/lib.rs @@ -43,7 +43,7 @@ use api_models::analytics::{ }; use clickhouse::ClickhouseClient; pub use clickhouse::ClickhouseConfig; -use error_stack::IntoReport; +use error_stack::report; use router_env::{ logger, tracing::{self, instrument}, @@ -512,7 +512,7 @@ impl AnalyticsProvider { time_range: &TimeRange, ) -> types::MetricsResult> { match self { - Self::Sqlx(_pool) => Err(MetricsError::NotImplemented).into_report(), + Self::Sqlx(_pool) => Err(report!(MetricsError::NotImplemented)), Self::Clickhouse(pool) => { metric .load_metrics(dimensions, pub_key, filters, granularity, time_range, pool) @@ -544,7 +544,7 @@ impl AnalyticsProvider { time_range: &TimeRange, ) -> types::MetricsResult> { match self { - Self::Sqlx(_pool) => Err(MetricsError::NotImplemented).into_report(), + Self::Sqlx(_pool) => Err(report!(MetricsError::NotImplemented)), Self::Clickhouse(ckh_pool) | Self::CombinedCkh(_, ckh_pool) | Self::CombinedSqlx(_, ckh_pool) => { diff --git a/crates/analytics/src/outgoing_webhook_event/core.rs b/crates/analytics/src/outgoing_webhook_event/core.rs index 5024cc70ec1..a78def2751e 100644 --- a/crates/analytics/src/outgoing_webhook_event/core.rs +++ b/crates/analytics/src/outgoing_webhook_event/core.rs @@ -1,6 +1,6 @@ use api_models::analytics::outgoing_webhook_event::OutgoingWebhookLogsRequest; use common_utils::errors::ReportSwitchExt; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use super::events::{get_outgoing_webhook_event, OutgoingWebhookLogsResult}; use crate::{errors::AnalyticsResult, types::FiltersError, AnalyticsProvider}; @@ -14,7 +14,6 @@ pub async fn outgoing_webhook_events_core( AnalyticsProvider::Sqlx(_) => Err(FiltersError::NotImplemented( "Outgoing Webhook Events Logs not implemented for SQLX", )) - .into_report() .attach_printable("SQL Analytics is not implemented for Outgoing Webhook Events"), AnalyticsProvider::Clickhouse(ckh_pool) | AnalyticsProvider::CombinedSqlx(_, ckh_pool) diff --git a/crates/analytics/src/payments/core.rs b/crates/analytics/src/payments/core.rs index 138e8878932..debc03fc9d5 100644 --- a/crates/analytics/src/payments/core.rs +++ b/crates/analytics/src/payments/core.rs @@ -10,7 +10,7 @@ use api_models::analytics::{ MetricsResponse, PaymentFiltersResponse, }; use common_utils::errors::CustomResult; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use router_env::{ instrument, logger, tracing::{self, Instrument}, @@ -115,7 +115,6 @@ pub async fn get_metrics( .join_next() .await .transpose() - .into_report() .change_context(AnalyticsError::UnknownError)? { match task_type { diff --git a/crates/analytics/src/query.rs b/crates/analytics/src/query.rs index 27e4154a1a9..a7ef0d993e8 100644 --- a/crates/analytics/src/query.rs +++ b/crates/analytics/src/query.rs @@ -18,7 +18,7 @@ use api_models::{ }; use common_utils::errors::{CustomResult, ParsingError}; use diesel_models::enums as storage_enums; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use router_env::{logger, Flow}; use super::types::{AnalyticsCollection, AnalyticsDataSource, LoadRow, TableEngine}; @@ -179,7 +179,6 @@ impl SeriesBucket for Granularity { time::Time::MIDNIGHT.replace_hour(clip_start(value.hour(), i)) } } - .into_report() .change_context(PostProcessingError::BucketClipping)?; Ok(value.replace_time(clipped_time)) @@ -206,7 +205,6 @@ impl SeriesBucket for Granularity { time::Time::MIDNIGHT.replace_hour(clip_end(value.hour(), i)) } } - .into_report() .change_context(PostProcessingError::BucketClipping) .attach_printable_lazy(|| format!("Bucket Clip Error: {value}"))?; @@ -644,8 +642,7 @@ where if self.columns.is_empty() { Err(QueryBuildingError::InvalidQuery( "No select fields provided", - )) - .into_report()?; + ))?; } let mut query = String::from("SELECT "); diff --git a/crates/analytics/src/refunds/core.rs b/crates/analytics/src/refunds/core.rs index 25a1e228f56..b53d482e620 100644 --- a/crates/analytics/src/refunds/core.rs +++ b/crates/analytics/src/refunds/core.rs @@ -8,7 +8,7 @@ use api_models::analytics::{ AnalyticsMetadata, GetRefundFilterRequest, GetRefundMetricRequest, MetricsResponse, RefundFilterValue, RefundFiltersResponse, }; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use router_env::{ logger, tracing::{self, Instrument}, @@ -66,7 +66,6 @@ pub async fn get_metrics( .join_next() .await .transpose() - .into_report() .change_context(AnalyticsError::UnknownError)? { let data = data?; diff --git a/crates/analytics/src/sdk_events/core.rs b/crates/analytics/src/sdk_events/core.rs index 46cc636f438..a5d2900e54d 100644 --- a/crates/analytics/src/sdk_events/core.rs +++ b/crates/analytics/src/sdk_events/core.rs @@ -8,7 +8,7 @@ use api_models::analytics::{ SdkEventFiltersResponse, }; use common_utils::errors::ReportSwitchExt; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use router_env::{instrument, logger, tracing}; use super::{ @@ -32,7 +32,6 @@ pub async fn sdk_events_core( AnalyticsProvider::Sqlx(_) => Err(FiltersError::NotImplemented( "SDK Events not implemented for SQLX", )) - .into_report() .attach_printable("SQL Analytics is not implemented for Sdk Events"), AnalyticsProvider::Clickhouse(pool) => get_sdk_event(&publishable_key, req, pool).await, AnalyticsProvider::CombinedSqlx(_sqlx_pool, ckh_pool) @@ -80,7 +79,6 @@ pub async fn get_metrics( .join_next() .await .transpose() - .into_report() .change_context(AnalyticsError::UnknownError)? { logger::info!("Logging Result {:?}", data); @@ -165,7 +163,6 @@ pub async fn get_filters( AnalyticsProvider::Sqlx(_pool) => Err(FiltersError::NotImplemented( "SDK Events not implemented for SQLX", )) - .into_report() .attach_printable("SQL Analytics is not implemented for SDK Events"), AnalyticsProvider::Clickhouse(pool) => { get_sdk_event_filter_for_dimension(dim, publishable_key, &req.time_range, pool) diff --git a/crates/analytics/src/sqlx.rs b/crates/analytics/src/sqlx.rs index e88fe519c3c..586ec1bfb17 100644 --- a/crates/analytics/src/sqlx.rs +++ b/crates/analytics/src/sqlx.rs @@ -8,7 +8,7 @@ use common_utils::errors::{CustomResult, ParsingError}; use diesel_models::enums::{ AttemptStatus, AuthenticationType, Currency, PaymentMethod, RefundStatus, }; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use masking::PeekInterface; use sqlx::{ postgres::{PgArgumentBuffer, PgPoolOptions, PgRow, PgTypeInfo, PgValueRef}, @@ -138,9 +138,7 @@ where for<'a> T: FromRow<'a, PgRow>, { fn load_row(row: PgRow) -> CustomResult { - T::from_row(&row) - .into_report() - .change_context(QueryExecutionError::RowExtractionFailure) + T::from_row(&row).change_context(QueryExecutionError::RowExtractionFailure) } } @@ -163,7 +161,6 @@ impl AnalyticsDataSource for SqlxClient { sqlx::query(&format!("{query};")) .fetch_all(&self.pool) .await - .into_report() .change_context(QueryExecutionError::DatabaseError) .attach_printable_lazy(|| format!("Failed to run query {query}"))? .into_iter() @@ -179,7 +176,6 @@ impl HealthCheck for SqlxClient { .fetch_all(&self.pool) .await .map(|_| ()) - .into_report() .change_context(QueryExecutionError::DatabaseError) } } diff --git a/crates/api_models/Cargo.toml b/crates/api_models/Cargo.toml index 94202935c55..356a29830ec 100644 --- a/crates/api_models/Cargo.toml +++ b/crates/api_models/Cargo.toml @@ -24,7 +24,7 @@ recon = [] [dependencies] actix-web = { version = "4.3.1", optional = true } -error-stack = "0.3.1" +error-stack = "0.4.1" mime = "0.3.17" reqwest = { version = "0.11.18", optional = true } serde = { version = "1.0.193", features = ["derive"] } diff --git a/crates/api_models/src/routing.rs b/crates/api_models/src/routing.rs index b82e5433e5a..4d32f1d0f81 100644 --- a/crates/api_models/src/routing.rs +++ b/crates/api_models/src/routing.rs @@ -1,7 +1,6 @@ use std::fmt::Debug; use common_utils::errors::ParsingError; -use error_stack::IntoReport; pub use euclid::{ dssa::types::EuclidAnalysable, frontend::{ @@ -379,14 +378,12 @@ impl TryFrom for RoutingAlgorithm { RoutingAlgorithmSerde::Priority(i) if i.is_empty() => { Err(ParsingError::StructParseFailure( "Connectors list can't be empty for Priority Algorithm", - )) - .into_report()? + ))? } RoutingAlgorithmSerde::VolumeSplit(i) if i.is_empty() => { Err(ParsingError::StructParseFailure( "Connectors list can't be empty for Volume split Algorithm", - )) - .into_report()? + ))? } _ => {} }; @@ -446,14 +443,12 @@ impl TryFrom for StraightThroughAlgorithm { StraightThroughAlgorithmInner::Priority(i) if i.is_empty() => { Err(ParsingError::StructParseFailure( "Connectors list can't be empty for Priority Algorithm", - )) - .into_report()? + ))? } StraightThroughAlgorithmInner::VolumeSplit(i) if i.is_empty() => { Err(ParsingError::StructParseFailure( "Connectors list can't be empty for Volume split Algorithm", - )) - .into_report()? + ))? } _ => {} }; diff --git a/crates/cards/Cargo.toml b/crates/cards/Cargo.toml index 6892350ce6f..bb185bf2167 100644 --- a/crates/cards/Cargo.toml +++ b/crates/cards/Cargo.toml @@ -10,7 +10,7 @@ license.workspace = true [features] [dependencies] -error-stack = "0.3.1" +error-stack = "0.4.1" luhn = "1.0.1" serde = { version = "1.0.193", features = ["derive"] } thiserror = "1.0.40" diff --git a/crates/common_utils/Cargo.toml b/crates/common_utils/Cargo.toml index e8b3b726cec..bc8a3af0a43 100644 --- a/crates/common_utils/Cargo.toml +++ b/crates/common_utils/Cargo.toml @@ -16,7 +16,7 @@ logs = ["dep:router_env"] async-trait = { version = "0.1.68", optional = true } bytes = "1.4.0" diesel = "2.1.0" -error-stack = "0.3.1" +error-stack = "0.4.1" futures = { version = "0.3.28", optional = true } hex = "0.4.3" http = "0.2.9" diff --git a/crates/common_utils/src/crypto.rs b/crates/common_utils/src/crypto.rs index 1a29f043e05..46904535f01 100644 --- a/crates/common_utils/src/crypto.rs +++ b/crates/common_utils/src/crypto.rs @@ -1,7 +1,7 @@ //! Utilities for cryptographic algorithms use std::ops::Deref; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use masking::{ExposeInterface, Secret}; use md5; use ring::{ @@ -248,18 +248,15 @@ impl EncodeMessage for GcmAes256 { secret: &[u8], msg: &[u8], ) -> CustomResult, errors::CryptoError> { - let nonce_sequence = NonceSequence::new() - .into_report() - .change_context(errors::CryptoError::EncodingFailed)?; + let nonce_sequence = + NonceSequence::new().change_context(errors::CryptoError::EncodingFailed)?; let current_nonce = nonce_sequence.current(); let key = UnboundKey::new(&aead::AES_256_GCM, secret) - .into_report() .change_context(errors::CryptoError::EncodingFailed)?; let mut key = SealingKey::new(key, nonce_sequence); let mut in_out = msg.to_vec(); key.seal_in_place_append_tag(aead::Aad::empty(), &mut in_out) - .into_report() .change_context(errors::CryptoError::EncodingFailed)?; in_out.splice(0..0, current_nonce); @@ -275,17 +272,15 @@ impl DecodeMessage for GcmAes256 { ) -> CustomResult, errors::CryptoError> { let msg = msg.expose(); let key = UnboundKey::new(&aead::AES_256_GCM, secret) - .into_report() .change_context(errors::CryptoError::DecodingFailed)?; let nonce_sequence = NonceSequence::from_bytes( - msg.get(..ring::aead::NONCE_LEN) - .ok_or(errors::CryptoError::DecodingFailed) - .into_report() - .attach_printable("Failed to read the nonce form the encrypted ciphertext")? - .try_into() - .into_report() - .change_context(errors::CryptoError::DecodingFailed)?, + <[u8; ring::aead::NONCE_LEN]>::try_from( + msg.get(..ring::aead::NONCE_LEN) + .ok_or(errors::CryptoError::DecodingFailed) + .attach_printable("Failed to read the nonce form the encrypted ciphertext")?, + ) + .change_context(errors::CryptoError::DecodingFailed)?, ); let mut key = OpeningKey::new(key, nonce_sequence); @@ -294,7 +289,6 @@ impl DecodeMessage for GcmAes256 { let result = key .open_within(aead::Aad::empty(), output, ring::aead::NONCE_LEN..) - .into_report() .change_context(errors::CryptoError::DecodingFailed)?; Ok(result.to_vec()) @@ -329,7 +323,6 @@ impl VerifySignature for Sha512 { msg: &[u8], ) -> CustomResult { let msg_str = std::str::from_utf8(msg) - .into_report() .change_context(errors::CryptoError::EncodingFailed)? .to_owned(); let hashed_digest = hex::encode( diff --git a/crates/common_utils/src/ext_traits.rs b/crates/common_utils/src/ext_traits.rs index 8f97dd75534..f71e098a99c 100644 --- a/crates/common_utils/src/ext_traits.rs +++ b/crates/common_utils/src/ext_traits.rs @@ -3,7 +3,7 @@ //! & inbuilt datatypes. //! -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use masking::{ExposeInterface, PeekInterface, Secret, Strategy}; use quick_xml::de; use serde::{Deserialize, Serialize}; @@ -101,7 +101,6 @@ where serde_json::to_string( &P::try_from(self).change_context(errors::ParsingError::UnknownError)?, ) - .into_report() .change_context(errors::ParsingError::EncodeError("string")) .attach_printable_lazy(|| format!("Unable to convert {self:?} to a request")) } @@ -115,7 +114,6 @@ where serde_urlencoded::to_string( &P::try_from(self).change_context(errors::ParsingError::UnknownError)?, ) - .into_report() .change_context(errors::ParsingError::EncodeError("url-encoded")) .attach_printable_lazy(|| format!("Unable to convert {self:?} to a request")) } @@ -126,7 +124,6 @@ where Self: Serialize, { serde_urlencoded::to_string(self) - .into_report() .change_context(errors::ParsingError::EncodeError("url-encoded")) .attach_printable_lazy(|| format!("Unable to convert {self:?} to a request")) } @@ -136,7 +133,6 @@ where Self: Serialize, { serde_json::to_string(self) - .into_report() .change_context(errors::ParsingError::EncodeError("json")) .attach_printable_lazy(|| format!("Unable to convert {self:?} to a request")) } @@ -146,7 +142,6 @@ where Self: Serialize, { quick_xml::se::to_string(self) - .into_report() .change_context(errors::ParsingError::EncodeError("xml")) .attach_printable_lazy(|| format!("Unable to convert {self:?} to a request")) } @@ -156,7 +151,6 @@ where Self: Serialize, { serde_json::to_value(self) - .into_report() .change_context(errors::ParsingError::EncodeError("json-value")) .attach_printable_lazy(|| format!("Unable to convert {self:?} to a value")) } @@ -166,7 +160,6 @@ where Self: Serialize, { serde_json::to_vec(self) - .into_report() .change_context(errors::ParsingError::EncodeError("byte-vec")) .attach_printable_lazy(|| format!("Unable to convert {self:?} to a value")) } @@ -198,7 +191,6 @@ impl BytesExt for bytes::Bytes { use bytes::Buf; serde_json::from_slice::(self.chunk()) - .into_report() .change_context(errors::ParsingError::StructParseFailure(type_name)) .attach_printable_lazy(|| { let variable_type = std::any::type_name::(); @@ -232,7 +224,6 @@ impl ByteSliceExt for [u8] { T: Deserialize<'de>, { serde_json::from_slice(self) - .into_report() .change_context(errors::ParsingError::StructParseFailure(type_name)) .attach_printable_lazy(|| format!("Unable to parse {type_name} from &[u8] {:?}", &self)) } @@ -260,7 +251,6 @@ impl ValueExt for serde_json::Value { &self ); serde_json::from_value::(self) - .into_report() .change_context(errors::ParsingError::StructParseFailure(type_name)) .attach_printable_lazy(|| debug) } @@ -318,7 +308,6 @@ impl StringExt for String { ::Err: std::error::Error + Send + Sync + 'static, { T::from_str(&self) - .into_report() .change_context(errors::ParsingError::EnumParseFailure(enum_name)) .attach_printable_lazy(|| format!("Invalid enum variant {self:?} for enum {enum_name}")) } @@ -331,7 +320,6 @@ impl StringExt for String { T: Deserialize<'de>, { serde_json::from_str::(self) - .into_report() .change_context(errors::ParsingError::StructParseFailure(type_name)) .attach_printable_lazy(|| { format!("Unable to parse {type_name} from string {:?}", &self) @@ -543,7 +531,6 @@ where Err(errors::ValidationError::MissingRequiredField { field_name: field_name.to_string(), }) - .into_report() .attach_printable(format!("Missing required field {field_name} in {self:?}")) }) } @@ -559,7 +546,6 @@ where None => Err(errors::ValidationError::MissingRequiredField { field_name: field_name.to_string(), }) - .into_report() .attach_printable(format!("Missing required field {field_name} in {self:?}")), } } @@ -576,7 +562,6 @@ where .change_context(errors::ParsingError::UnknownError)?; E::from_str(value.as_ref()) - .into_report() .change_context(errors::ParsingError::UnknownError) .attach_printable_lazy(|| format!("Invalid {{ {enum_name}: {value:?} }} ")) } diff --git a/crates/common_utils/src/pii.rs b/crates/common_utils/src/pii.rs index 110a7eb952c..c1f9d716e4b 100644 --- a/crates/common_utils/src/pii.rs +++ b/crates/common_utils/src/pii.rs @@ -10,7 +10,7 @@ use diesel::{ serialize::{Output, ToSql}, sql_types, AsExpression, }; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use masking::{ExposeInterface, Secret, Strategy, WithType}; #[cfg(feature = "logs")] use router_env::logger; @@ -308,8 +308,8 @@ impl FromStr for Email { } Err(_) => Err(ValidationError::InvalidValue { message: "Invalid email address format".into(), - }) - .into_report(), + } + .into()), } } } diff --git a/crates/common_utils/src/types.rs b/crates/common_utils/src/types.rs index 7dfadd54a84..418ce591fd2 100644 --- a/crates/common_utils/src/types.rs +++ b/crates/common_utils/src/types.rs @@ -8,7 +8,7 @@ use diesel::{ sql_types::Jsonb, AsExpression, FromSqlRow, }; -use error_stack::{IntoReport, ResultExt}; +use error_stack::{report, ResultExt}; use semver::Version; use serde::{de::Visitor, Deserialize, Deserializer}; @@ -37,12 +37,11 @@ impl Percentage { if Self::is_valid_string_value(&value)? { Ok(Self { percentage: value - .parse() - .into_report() + .parse::() .change_context(PercentageError::InvalidPercentageValue)?, }) } else { - Err(PercentageError::InvalidPercentageValue.into()) + Err(report!(PercentageError::InvalidPercentageValue)) .attach_printable(get_invalid_percentage_error_message(PRECISION)) } } @@ -57,11 +56,10 @@ impl Percentage { let max_amount = i64::MAX / 10000; if amount > max_amount { // value gets rounded off after i64::MAX/10000 - Err(PercentageError::UnableToApplyPercentage { + Err(report!(PercentageError::UnableToApplyPercentage { percentage: self.percentage, amount, - } - .into()) + })) .attach_printable(format!( "Cannot calculate percentage for amount greater than {}", max_amount @@ -78,8 +76,7 @@ impl Percentage { } fn is_valid_float_string(value: &str) -> CustomResult { value - .parse() - .into_report() + .parse::() .change_context(PercentageError::InvalidPercentageValue) } fn is_valid_range(value: f32) -> bool { @@ -182,7 +179,7 @@ impl FromStr for SemanticVersion { type Err = error_stack::Report; fn from_str(s: &str) -> Result { - Ok(Self(Version::from_str(s).into_report().change_context( + Ok(Self(Version::from_str(s).change_context( ParsingError::StructParseFailure("SemanticVersion"), )?)) } diff --git a/crates/data_models/Cargo.toml b/crates/data_models/Cargo.toml index 9d4447b0c08..090983246d7 100644 --- a/crates/data_models/Cargo.toml +++ b/crates/data_models/Cargo.toml @@ -22,7 +22,7 @@ diesel_models = { version = "0.1.0", path = "../diesel_models", features = ["kv_ # Third party deps async-trait = "0.1.68" -error-stack = "0.3.1" +error-stack = "0.4.1" serde = { version = "1.0.193", features = ["derive"] } serde_json = "1.0.108" thiserror = "1.0.40" diff --git a/crates/data_models/src/mandates.rs b/crates/data_models/src/mandates.rs index fa22a4e57d5..912ddc67058 100644 --- a/crates/data_models/src/mandates.rs +++ b/crates/data_models/src/mandates.rs @@ -5,7 +5,7 @@ use api_models::payments::{ }; use common_enums::Currency; use common_utils::{date_time, errors::ParsingError, pii}; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use masking::{PeekInterface, Secret}; use time::PrimitiveDateTime; @@ -182,7 +182,6 @@ impl MandateAmountData { self.end_date .map(|date| { date_time::format_date(date, format) - .into_report() .change_context(ParsingError::DateTimeParsingError) }) .transpose() diff --git a/crates/diesel_models/Cargo.toml b/crates/diesel_models/Cargo.toml index 35a86f2e85c..d0ef6169335 100644 --- a/crates/diesel_models/Cargo.toml +++ b/crates/diesel_models/Cargo.toml @@ -14,7 +14,7 @@ kv_store = [] [dependencies] async-bb8-diesel = { git = "https://github.com/jarnura/async-bb8-diesel", rev = "53b4ab901aab7635c8215fd1c2d542c8db443094" } diesel = { version = "2.1.0", features = ["postgres", "serde_json", "time", "64-column-tables"] } -error-stack = "0.3.1" +error-stack = "0.4.1" frunk = "0.4.1" frunk_core = "0.4.1" serde = { version = "1.0.193", features = ["derive"] } diff --git a/crates/diesel_models/src/kv.rs b/crates/diesel_models/src/kv.rs index cc67deb40c5..38429b414bb 100644 --- a/crates/diesel_models/src/kv.rs +++ b/crates/diesel_models/src/kv.rs @@ -1,4 +1,4 @@ -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use serde::{Deserialize, Serialize}; use crate::{ @@ -123,7 +123,6 @@ impl TypedSql { ( "typed_sql", serde_json::to_string(self) - .into_report() .change_context(errors::DatabaseError::QueryGenerationFailed)?, ), ("global_id", global_id), diff --git a/crates/diesel_models/src/query/events.rs b/crates/diesel_models/src/query/events.rs index 0fc856d600c..1d92baaac46 100644 --- a/crates/diesel_models/src/query/events.rs +++ b/crates/diesel_models/src/query/events.rs @@ -59,7 +59,7 @@ impl Event { ) -> StorageResult> { use async_bb8_diesel::AsyncRunQueryDsl; use diesel::{debug_query, pg::Pg, QueryDsl}; - use error_stack::{IntoReport, ResultExt}; + use error_stack::ResultExt; use router_env::logger; use super::generics::db_metrics::{track_database_call, DatabaseOperation}; @@ -95,7 +95,6 @@ impl Event { track_database_call::(query.get_results_async(conn), DatabaseOperation::Filter) .await - .into_report() .change_context(DatabaseError::Others) // Query returns empty Vec when no records are found .attach_printable("Error filtering events by constraints") } @@ -146,7 +145,7 @@ impl Event { ) -> StorageResult> { use async_bb8_diesel::AsyncRunQueryDsl; use diesel::{debug_query, pg::Pg, QueryDsl}; - use error_stack::{IntoReport, ResultExt}; + use error_stack::ResultExt; use router_env::logger; use super::generics::db_metrics::{track_database_call, DatabaseOperation}; @@ -182,7 +181,6 @@ impl Event { track_database_call::(query.get_results_async(conn), DatabaseOperation::Filter) .await - .into_report() .change_context(DatabaseError::Others) // Query returns empty Vec when no records are found .attach_printable("Error filtering events by constraints") } diff --git a/crates/diesel_models/src/query/generics.rs b/crates/diesel_models/src/query/generics.rs index 27c3d8706af..0527ff3a181 100644 --- a/crates/diesel_models/src/query/generics.rs +++ b/crates/diesel_models/src/query/generics.rs @@ -19,7 +19,7 @@ use diesel::{ result::Error as DieselError, Expression, Insertable, QueryDsl, QuerySource, Table, }; -use error_stack::{report, IntoReport, ResultExt}; +use error_stack::{report, ResultExt}; use router_env::logger; use crate::{errors, PgPooledConn, StorageResult}; @@ -86,14 +86,13 @@ where match track_database_call::(query.get_result_async(conn), DatabaseOperation::Insert) .await - .into_report() { Ok(value) => Ok(value), - Err(err) => match err.current_context() { + Err(err) => match err { DieselError::DatabaseError(diesel::result::DatabaseErrorKind::UniqueViolation, _) => { - Err(err).change_context(errors::DatabaseError::UniqueViolation) + Err(report!(err)).change_context(errors::DatabaseError::UniqueViolation) } - _ => Err(err).change_context(errors::DatabaseError::Others), + _ => Err(report!(err)).change_context(errors::DatabaseError::Others), }, } .attach_printable_lazy(|| format!("Error while inserting {debug_values}")) @@ -121,7 +120,6 @@ where track_database_call::(query.execute_async(conn), DatabaseOperation::Update) .await - .into_report() .change_context(errors::DatabaseError::Others) .attach_printable_lazy(|| format!("Error while updating {debug_values}")) } @@ -205,7 +203,6 @@ where } else { vec_r.pop().ok_or(errors::DatabaseError::Others) } - .into_report() .attach_printable("Maybe not queried using a unique key") })? } @@ -274,7 +271,6 @@ where track_database_call::(query.execute_async(conn), DatabaseOperation::Delete) .await - .into_report() .change_context(errors::DatabaseError::Others) .attach_printable("Error while deleting") .and_then(|result| match result { @@ -310,7 +306,6 @@ where DatabaseOperation::DeleteWithResult, ) .await - .into_report() .change_context(errors::DatabaseError::Others) .attach_printable("Error while deleting") .and_then(|result| { @@ -332,14 +327,14 @@ where let query = ::table().find(id.to_owned()); logger::debug!(query = %debug_query::(&query).to_string()); - match track_database_call::(query.first_async(conn), DatabaseOperation::FindOne) - .await - .into_report() + match track_database_call::(query.first_async(conn), DatabaseOperation::FindOne).await { Ok(value) => Ok(value), - Err(err) => match err.current_context() { - DieselError::NotFound => Err(err).change_context(errors::DatabaseError::NotFound), - _ => Err(err).change_context(errors::DatabaseError::Others), + Err(err) => match err { + DieselError::NotFound => { + Err(report!(err)).change_context(errors::DatabaseError::NotFound) + } + _ => Err(report!(err)).change_context(errors::DatabaseError::Others), }, } .attach_printable_lazy(|| format!("Error finding record by primary key: {id:?}")) @@ -382,10 +377,9 @@ where track_database_call::(query.get_result_async(conn), DatabaseOperation::FindOne) .await - .into_report() - .map_err(|err| match err.current_context() { - DieselError::NotFound => err.change_context(errors::DatabaseError::NotFound), - _ => err.change_context(errors::DatabaseError::Others), + .map_err(|err| match err { + DieselError::NotFound => report!(err).change_context(errors::DatabaseError::NotFound), + _ => report!(err).change_context(errors::DatabaseError::Others), }) .attach_printable("Error finding record by predicate") } @@ -449,7 +443,6 @@ where track_database_call::(query.get_results_async(conn), DatabaseOperation::Filter) .await - .into_report() .change_context(errors::DatabaseError::NotFound) .attach_printable("Error filtering records by predicate") } diff --git a/crates/diesel_models/src/query/payment_attempt.rs b/crates/diesel_models/src/query/payment_attempt.rs index 7e44059927b..0133c52c5db 100644 --- a/crates/diesel_models/src/query/payment_attempt.rs +++ b/crates/diesel_models/src/query/payment_attempt.rs @@ -5,7 +5,7 @@ use diesel::{ associations::HasTable, debug_query, pg::Pg, BoolExpressionMethods, ExpressionMethods, QueryDsl, Table, }; -use error_stack::{IntoReport, ResultExt}; +use error_stack::{report, ResultExt}; use super::generics; use crate::{ @@ -89,30 +89,20 @@ impl PaymentAttempt { merchant_id: &str, ) -> StorageResult { // perform ordering on the application level instead of database level - generics::generic_filter::< - ::Table, - _, - <::Table as Table>::PrimaryKey, - Self, - >( + generics::generic_filter::<::Table, _, _, Self>( conn, dsl::payment_id .eq(payment_id.to_owned()) .and(dsl::merchant_id.eq(merchant_id.to_owned())) .and(dsl::status.eq(enums::AttemptStatus::Charged)), + Some(1), None, - None, - None, + Some(dsl::modified_at.desc()), ) .await? .into_iter() - .fold( - Err(DatabaseError::NotFound).into_report(), - |acc, cur| match acc { - Ok(value) if value.modified_at > cur.modified_at => Ok(value), - _ => Ok(cur), - }, - ) + .nth(0) + .ok_or(report!(DatabaseError::NotFound)) } pub async fn find_last_successful_or_partially_captured_attempt_by_payment_id_merchant_id( @@ -121,12 +111,7 @@ impl PaymentAttempt { merchant_id: &str, ) -> StorageResult { // perform ordering on the application level instead of database level - generics::generic_filter::< - ::Table, - _, - <::Table as Table>::PrimaryKey, - Self, - >( + generics::generic_filter::<::Table, _, _, Self>( conn, dsl::payment_id .eq(payment_id.to_owned()) @@ -136,19 +121,14 @@ impl PaymentAttempt { .eq(enums::AttemptStatus::Charged) .or(dsl::status.eq(enums::AttemptStatus::PartialCharged)), ), + Some(1), None, - None, - None, + Some(dsl::modified_at.desc()), ) .await? .into_iter() - .fold( - Err(DatabaseError::NotFound).into_report(), - |acc, cur| match acc { - Ok(value) if value.modified_at > cur.modified_at => Ok(value), - _ => Ok(cur), - }, - ) + .nth(0) + .ok_or(report!(DatabaseError::NotFound)) } pub async fn find_by_merchant_id_connector_txn_id( @@ -266,7 +246,6 @@ impl PaymentAttempt { .distinct() .get_results_async::>(conn) .await - .into_report() .change_context(errors::DatabaseError::Others) .attach_printable("Error filtering records by connector")? .into_iter() @@ -279,7 +258,6 @@ impl PaymentAttempt { .distinct() .get_results_async::>(conn) .await - .into_report() .change_context(DatabaseError::Others) .attach_printable("Error filtering records by currency")? .into_iter() @@ -292,7 +270,6 @@ impl PaymentAttempt { .distinct() .get_results_async::>(conn) .await - .into_report() .change_context(DatabaseError::Others) .attach_printable("Error filtering records by payment method")? .into_iter() @@ -305,7 +282,6 @@ impl PaymentAttempt { .distinct() .get_results_async::>(conn) .await - .into_report() .change_context(DatabaseError::Others) .attach_printable("Error filtering records by payment method type")? .into_iter() @@ -318,7 +294,6 @@ impl PaymentAttempt { .distinct() .get_results_async::>(conn) .await - .into_report() .change_context(DatabaseError::Others) .attach_printable("Error filtering records by authentication type")? .into_iter() @@ -369,7 +344,6 @@ impl PaymentAttempt { db_metrics::DatabaseOperation::Filter, ) .await - .into_report() .change_context(errors::DatabaseError::Others) .attach_printable("Error filtering count of payments") } diff --git a/crates/diesel_models/src/query/payment_method.rs b/crates/diesel_models/src/query/payment_method.rs index a27a2ae8950..7acf49a1570 100644 --- a/crates/diesel_models/src/query/payment_method.rs +++ b/crates/diesel_models/src/query/payment_method.rs @@ -3,7 +3,7 @@ use diesel::{ associations::HasTable, debug_query, pg::Pg, BoolExpressionMethods, ExpressionMethods, QueryDsl, Table, }; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use super::generics; use crate::{ @@ -124,7 +124,6 @@ impl PaymentMethod { generics::db_metrics::DatabaseOperation::Count, ) .await - .into_report() .change_context(errors::DatabaseError::Others) .attach_printable("Failed to get a count of payment methods") } diff --git a/crates/diesel_models/src/query/payout_attempt.rs b/crates/diesel_models/src/query/payout_attempt.rs index 085423710f0..ac34ee695ac 100644 --- a/crates/diesel_models/src/query/payout_attempt.rs +++ b/crates/diesel_models/src/query/payout_attempt.rs @@ -6,7 +6,7 @@ use diesel::{ query_dsl::methods::{DistinctDsl, FilterDsl, SelectDsl}, BoolExpressionMethods, ExpressionMethods, }; -use error_stack::{report, IntoReport, ResultExt}; +use error_stack::{report, ResultExt}; use super::generics; use crate::{ @@ -161,7 +161,6 @@ impl PayoutAttempt { .distinct() .get_results_async::>(conn) .await - .into_report() .change_context(errors::DatabaseError::Others) .attach_printable("Error filtering records by connector")? .into_iter() @@ -173,7 +172,6 @@ impl PayoutAttempt { .distinct() .get_results_async::(conn) .await - .into_report() .change_context(DatabaseError::Others) .attach_printable("Error filtering records by currency")? .into_iter() @@ -184,7 +182,6 @@ impl PayoutAttempt { .distinct() .get_results_async::(conn) .await - .into_report() .change_context(DatabaseError::Others) .attach_printable("Error filtering records by payout type")? .into_iter() diff --git a/crates/diesel_models/src/query/routing_algorithm.rs b/crates/diesel_models/src/query/routing_algorithm.rs index 28a5e6816e3..75a1f37f179 100644 --- a/crates/diesel_models/src/query/routing_algorithm.rs +++ b/crates/diesel_models/src/query/routing_algorithm.rs @@ -1,6 +1,6 @@ use async_bb8_diesel::AsyncRunQueryDsl; use diesel::{associations::HasTable, BoolExpressionMethods, ExpressionMethods, QueryDsl}; -use error_stack::{IntoReport, ResultExt}; +use error_stack::{report, ResultExt}; use time::PrimitiveDateTime; use crate::{ @@ -78,12 +78,10 @@ impl RoutingAlgorithm { enums::TransactionType, )>(conn) .await - .into_report() .change_context(DatabaseError::Others)? .into_iter() .next() - .ok_or(DatabaseError::NotFound) - .into_report() + .ok_or(report!(DatabaseError::NotFound)) .map( |( profile_id, @@ -138,7 +136,6 @@ impl RoutingAlgorithm { enums::TransactionType, )>(conn) .await - .into_report() .change_context(DatabaseError::Others)? .into_iter() .map( @@ -197,7 +194,6 @@ impl RoutingAlgorithm { enums::TransactionType, )>(conn) .await - .into_report() .change_context(DatabaseError::Others)? .into_iter() .map( @@ -260,7 +256,6 @@ impl RoutingAlgorithm { enums::TransactionType, )>(conn) .await - .into_report() .change_context(DatabaseError::Others)? .into_iter() .map( diff --git a/crates/diesel_models/src/query/user.rs b/crates/diesel_models/src/query/user.rs index 9254a04de25..77d245cf596 100644 --- a/crates/diesel_models/src/query/user.rs +++ b/crates/diesel_models/src/query/user.rs @@ -3,7 +3,7 @@ use diesel::{ associations::HasTable, debug_query, result::Error as DieselError, ExpressionMethods, JoinOnDsl, QueryDsl, }; -use error_stack::IntoReport; +use error_stack::report; use router_env::logger; pub mod sample_data; @@ -99,10 +99,11 @@ impl User { query .get_results_async::<(Self, UserRole)>(conn) .await - .into_report() - .map_err(|err| match err.current_context() { - DieselError::NotFound => err.change_context(errors::DatabaseError::NotFound), - _ => err.change_context(errors::DatabaseError::Others), + .map_err(|err| match err { + DieselError::NotFound => { + report!(err).change_context(errors::DatabaseError::NotFound) + } + _ => report!(err).change_context(errors::DatabaseError::Others), }) } } diff --git a/crates/diesel_models/src/query/user/sample_data.rs b/crates/diesel_models/src/query/user/sample_data.rs index a8ec2c3b0a4..3a26b2cda8d 100644 --- a/crates/diesel_models/src/query/user/sample_data.rs +++ b/crates/diesel_models/src/query/user/sample_data.rs @@ -1,6 +1,6 @@ use async_bb8_diesel::AsyncRunQueryDsl; use diesel::{associations::HasTable, debug_query, ExpressionMethods, TextExpressionMethods}; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use router_env::logger; use crate::{ @@ -25,7 +25,6 @@ pub async fn insert_payment_intents( query .get_results_async(conn) .await - .into_report() .change_context(errors::DatabaseError::Others) .attach_printable("Error while inserting payment intents") } @@ -40,7 +39,6 @@ pub async fn insert_payment_attempts( query .get_results_async(conn) .await - .into_report() .change_context(errors::DatabaseError::Others) .attach_printable("Error while inserting payment attempts") } @@ -56,7 +54,6 @@ pub async fn insert_refunds( query .get_results_async(conn) .await - .into_report() .change_context(errors::DatabaseError::Others) .attach_printable("Error while inserting refunds") } @@ -74,7 +71,6 @@ pub async fn delete_payment_intents( query .get_results_async(conn) .await - .into_report() .change_context(errors::DatabaseError::Others) .attach_printable("Error while deleting payment intents") .and_then(|result| match result.len() { @@ -100,7 +96,6 @@ pub async fn delete_payment_attempts( query .get_results_async(conn) .await - .into_report() .change_context(errors::DatabaseError::Others) .attach_printable("Error while deleting payment attempts") .and_then(|result| match result.len() { @@ -124,7 +119,6 @@ pub async fn delete_refunds(conn: &PgPooledConn, merchant_id: &str) -> StorageRe query .get_results_async(conn) .await - .into_report() .change_context(errors::DatabaseError::Others) .attach_printable("Error while deleting refunds") .and_then(|result| match result.len() { diff --git a/crates/drainer/Cargo.toml b/crates/drainer/Cargo.toml index 2eea5b513cc..4a2f7f1720e 100644 --- a/crates/drainer/Cargo.toml +++ b/crates/drainer/Cargo.toml @@ -18,7 +18,7 @@ bb8 = "0.8" clap = { version = "4.3.2", default-features = false, features = ["std", "derive", "help", "usage"] } config = { version = "0.13.3", features = ["toml"] } diesel = { version = "2.1.0", features = ["postgres"] } -error-stack = "0.3.1" +error-stack = "0.4.1" mime = "0.3.17" once_cell = "1.18.0" reqwest = { version = "0.11.18" } diff --git a/crates/drainer/src/lib.rs b/crates/drainer/src/lib.rs index e7ae7621365..56f2db0907e 100644 --- a/crates/drainer/src/lib.rs +++ b/crates/drainer/src/lib.rs @@ -16,7 +16,7 @@ mod secrets_transformers; use actix_web::dev::Server; use common_utils::signals::get_allowed_signals; use diesel_models::kv; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use hyperswitch_interfaces::secrets_interface::secret_state::RawSecret; use router_env::{ instrument, @@ -35,12 +35,9 @@ pub async fn start_drainer(store: Arc, conf: DrainerSettings) -> errors:: let (tx, rx) = mpsc::channel::<()>(1); - let signal = - get_allowed_signals() - .into_report() - .change_context(errors::DrainerError::SignalError( - "Failed while getting allowed signals".to_string(), - ))?; + let signal = get_allowed_signals().change_context(errors::DrainerError::SignalError( + "Failed while getting allowed signals".to_string(), + ))?; let handle = signal.handle(); let task_handle = tokio::spawn(common_utils::signals::signal_handler(signal, tx.clone()).in_current_span()); diff --git a/crates/drainer/src/stream.rs b/crates/drainer/src/stream.rs index b2775ac4ba1..319fc2b0e1d 100644 --- a/crates/drainer/src/stream.rs +++ b/crates/drainer/src/stream.rs @@ -1,6 +1,5 @@ use std::collections::HashMap; -use error_stack::IntoReport; use redis_interface as redis; use router_env::{logger, tracing}; @@ -66,7 +65,6 @@ impl Store { .stream_read_entries(stream_name, stream_id, Some(max_read_count)) .await .map_err(errors::DrainerError::from) - .into_report() }) .await; @@ -76,7 +74,7 @@ impl Store { &[metrics::KeyValue::new("stream", stream_name.to_owned())], ); - output + Ok(output?) } pub async fn trim_from_stream( &self, @@ -92,16 +90,14 @@ impl Store { .redis_conn .stream_trim_entries(stream_name, (trim_kind, trim_type, trim_id)) .await - .map_err(errors::DrainerError::from) - .into_report()?; + .map_err(errors::DrainerError::from)?; // Since xtrim deletes entries below given id excluding the given id. // Hence, deleting the minimum entry id self.redis_conn .stream_delete_entries(stream_name, minimum_entry_id) .await - .map_err(errors::DrainerError::from) - .into_report()?; + .map_err(errors::DrainerError::from)?; Ok(trim_result) }) diff --git a/crates/drainer/src/types.rs b/crates/drainer/src/types.rs index f1ddf8ef27e..a61a0fd159c 100644 --- a/crates/drainer/src/types.rs +++ b/crates/drainer/src/types.rs @@ -1,7 +1,7 @@ use std::collections::HashMap; use common_utils::errors; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use serde::{de::value::MapDeserializer, Deserialize, Serialize}; use crate::{ @@ -30,7 +30,6 @@ impl StreamData { >::new(hashmap.into_iter()); Self::deserialize(iter) - .into_report() .change_context(errors::ParsingError::StructParseFailure("StreamData")) } } diff --git a/crates/drainer/src/utils.rs b/crates/drainer/src/utils.rs index e27e04c30e6..c8c6e312f14 100644 --- a/crates/drainer/src/utils.rs +++ b/crates/drainer/src/utils.rs @@ -1,6 +1,6 @@ use std::sync::{atomic, Arc}; -use error_stack::IntoReport; +use error_stack::report; use redis_interface as redis; use serde::de::Deserialize; @@ -13,14 +13,11 @@ pub fn parse_stream_entries<'a>( read_result: &'a StreamReadResult, stream_name: &str, ) -> errors::DrainerResult<&'a StreamEntries> { - read_result - .get(stream_name) - .ok_or_else(|| { - errors::DrainerError::RedisError(error_stack::report!( - redis::errors::RedisError::NotFound - )) - }) - .into_report() + read_result.get(stream_name).ok_or_else(|| { + report!(errors::DrainerError::RedisError(report!( + redis::errors::RedisError::NotFound + ))) + }) } pub(crate) fn deserialize_i64<'de, D>(deserializer: D) -> Result diff --git a/crates/external_services/Cargo.toml b/crates/external_services/Cargo.toml index e1ee11495e7..f19216f74d7 100644 --- a/crates/external_services/Cargo.toml +++ b/crates/external_services/Cargo.toml @@ -23,7 +23,7 @@ aws-sdk-s3 = { version = "0.28.0", optional = true } aws-smithy-client = "0.55.3" base64 = "0.21.2" dyn-clone = "1.0.11" -error-stack = "0.3.1" +error-stack = "0.4.1" once_cell = "1.18.0" serde = { version = "1.0.193", features = ["derive"] } thiserror = "1.0.40" diff --git a/crates/external_services/src/aws_kms/core.rs b/crates/external_services/src/aws_kms/core.rs index d211f1def9b..f63c2000fe8 100644 --- a/crates/external_services/src/aws_kms/core.rs +++ b/crates/external_services/src/aws_kms/core.rs @@ -6,7 +6,7 @@ use aws_config::meta::region::RegionProviderChain; use aws_sdk_kms::{config::Region, primitives::Blob, Client}; use base64::Engine; use common_utils::errors::CustomResult; -use error_stack::{IntoReport, ResultExt}; +use error_stack::{report, ResultExt}; use router_env::logger; use crate::{consts, metrics}; @@ -49,7 +49,6 @@ impl AwsKmsClient { let start = Instant::now(); let data = consts::BASE64_ENGINE .decode(data) - .into_report() .change_context(AwsKmsError::Base64DecodingFailed)?; let ciphertext_blob = Blob::new(data); @@ -67,17 +66,13 @@ impl AwsKmsClient { metrics::AWS_KMS_DECRYPTION_FAILURES.add(&metrics::CONTEXT, 1, &[]); error }) - .into_report() .change_context(AwsKmsError::DecryptionFailed)?; let output = decrypt_output .plaintext - .ok_or(AwsKmsError::MissingPlaintextDecryptionOutput) - .into_report() + .ok_or(report!(AwsKmsError::MissingPlaintextDecryptionOutput)) .and_then(|blob| { - String::from_utf8(blob.into_inner()) - .into_report() - .change_context(AwsKmsError::Utf8DecodingFailed) + String::from_utf8(blob.into_inner()).change_context(AwsKmsError::Utf8DecodingFailed) })?; let time_taken = start.elapsed(); @@ -108,13 +103,11 @@ impl AwsKmsClient { metrics::AWS_KMS_ENCRYPTION_FAILURES.add(&metrics::CONTEXT, 1, &[]); error }) - .into_report() .change_context(AwsKmsError::EncryptionFailed)?; let output = encrypted_output .ciphertext_blob .ok_or(AwsKmsError::MissingCiphertextEncryptionOutput) - .into_report() .map(|blob| consts::BASE64_ENGINE.encode(blob.into_inner()))?; let time_taken = start.elapsed(); metrics::AWS_KMS_ENCRYPT_TIME.record(&metrics::CONTEXT, time_taken.as_secs_f64(), &[]); diff --git a/crates/external_services/src/email/ses.rs b/crates/external_services/src/email/ses.rs index de4d7794918..73599b344cd 100644 --- a/crates/external_services/src/email/ses.rs +++ b/crates/external_services/src/email/ses.rs @@ -8,7 +8,7 @@ use aws_sdk_sesv2::{ }; use aws_sdk_sts::config::Credentials; use common_utils::{errors::CustomResult, ext_traits::OptionExt, pii}; -use error_stack::{report, IntoReport, ResultExt}; +use error_stack::{report, ResultExt}; use hyper::Uri; use masking::PeekInterface; use router_env::logger; @@ -102,7 +102,6 @@ impl AwsSes { .role_session_name(&ses_config.sts_role_session_name) .send() .await - .into_report() .change_context(AwsSesError::AssumeRoleFailure { region: conf.aws_region.to_owned(), role_arn: ses_config.email_role_arn.to_owned(), @@ -181,14 +180,12 @@ impl AwsSes { let proxy_uri = proxy_url .as_ref() .parse::() - .into_report() .attach_printable("Unable to parse the proxy url {proxy_url}") .change_context(AwsSesError::BuildingProxyConnectorFailed)?; let proxy = hyper_proxy::Proxy::new(hyper_proxy::Intercept::All, proxy_uri); hyper_proxy::ProxyConnector::from_proxy(hyper::client::HttpConnector::new(), proxy) - .into_report() .change_context(AwsSesError::BuildingProxyConnectorFailed) } } @@ -247,7 +244,6 @@ impl EmailClient for AwsSes { .send() .await .map_err(AwsSesError::SendingFailure) - .into_report() .change_context(EmailError::EmailSendingFailure)?; Ok(()) diff --git a/crates/external_services/src/file_storage/file_system.rs b/crates/external_services/src/file_storage/file_system.rs index 15ca84deeb8..2c1ec287f5f 100644 --- a/crates/external_services/src/file_storage/file_system.rs +++ b/crates/external_services/src/file_storage/file_system.rs @@ -9,7 +9,7 @@ use std::{ }; use common_utils::errors::CustomResult; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use crate::file_storage::{FileStorageError, FileStorageInterface}; @@ -45,18 +45,14 @@ impl FileSystem { file_path .parent() .ok_or(FileSystemStorageError::CreateDirFailed) - .into_report() .attach_printable("Failed to obtain parent directory")?, ) - .into_report() .change_context(FileSystemStorageError::CreateDirFailed)?; - let mut file_handler = File::create(file_path) - .into_report() - .change_context(FileSystemStorageError::CreateFailure)?; + let mut file_handler = + File::create(file_path).change_context(FileSystemStorageError::CreateFailure)?; file_handler .write_all(&file) - .into_report() .change_context(FileSystemStorageError::WriteFailure)?; Ok(()) } @@ -64,9 +60,7 @@ impl FileSystem { /// Deletes the file associated with the specified file key from the file system. async fn delete_file(&self, file_key: &str) -> CustomResult<(), FileSystemStorageError> { let file_path = get_file_path(file_key); - remove_file(file_path) - .into_report() - .change_context(FileSystemStorageError::DeleteFailure)?; + remove_file(file_path).change_context(FileSystemStorageError::DeleteFailure)?; Ok(()) } @@ -74,11 +68,9 @@ impl FileSystem { async fn retrieve_file(&self, file_key: &str) -> CustomResult, FileSystemStorageError> { let mut received_data: Vec = Vec::new(); let file_path = get_file_path(file_key); - let mut file = File::open(file_path) - .into_report() - .change_context(FileSystemStorageError::FileOpenFailure)?; + let mut file = + File::open(file_path).change_context(FileSystemStorageError::FileOpenFailure)?; file.read_to_end(&mut received_data) - .into_report() .change_context(FileSystemStorageError::ReadFailure)?; Ok(received_data) } diff --git a/crates/external_services/src/no_encryption/implementers.rs b/crates/external_services/src/no_encryption/implementers.rs index f67c7c85fd5..b880c3c1303 100644 --- a/crates/external_services/src/no_encryption/implementers.rs +++ b/crates/external_services/src/no_encryption/implementers.rs @@ -1,7 +1,7 @@ //! Trait implementations for No encryption client use common_utils::errors::CustomResult; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use hyperswitch_interfaces::{ encryption_interface::{EncryptionError, EncryptionManagementInterface}, secrets_interface::{SecretManagementInterface, SecretsManagementError}, @@ -29,7 +29,6 @@ impl SecretManagementInterface for NoEncryption { ) -> CustomResult, SecretsManagementError> { String::from_utf8(self.decrypt(input.expose())) .map(Into::into) - .into_report() .change_context(SecretsManagementError::FetchSecretFailed) .attach_printable("Failed to convert decrypted value to UTF-8") } diff --git a/crates/pm_auth/Cargo.toml b/crates/pm_auth/Cargo.toml index 9654932d5ef..ef21539d4fa 100644 --- a/crates/pm_auth/Cargo.toml +++ b/crates/pm_auth/Cargo.toml @@ -18,7 +18,7 @@ router_env = { version = "0.1.0", path = "../router_env", features = ["log_extra # Third party crates async-trait = "0.1.66" bytes = "1.4.0" -error-stack = "0.3.1" +error-stack = "0.4.1" http = "0.2.9" mime = "0.3.17" serde = "1.0.193" diff --git a/crates/redis_interface/Cargo.toml b/crates/redis_interface/Cargo.toml index 85cfef3df54..233781b52e4 100644 --- a/crates/redis_interface/Cargo.toml +++ b/crates/redis_interface/Cargo.toml @@ -8,7 +8,7 @@ readme = "README.md" license.workspace = true [dependencies] -error-stack = "0.3.1" +error-stack = "0.4.1" fred = { version = "7.1.2", features = ["metrics", "partial-tracing", "subscriber-client", "check-unresponsive"] } futures = "0.3" serde = { version = "1.0.193", features = ["derive"] } diff --git a/crates/redis_interface/src/commands.rs b/crates/redis_interface/src/commands.rs index eb02e9bc82f..21630fc3c08 100644 --- a/crates/redis_interface/src/commands.rs +++ b/crates/redis_interface/src/commands.rs @@ -13,7 +13,7 @@ use common_utils::{ ext_traits::{AsyncExt, ByteSliceExt, Encode, StringExt}, fp_utils, }; -use error_stack::{IntoReport, ResultExt}; +use error_stack::{report, ResultExt}; use fred::{ interfaces::{HashesInterface, KeysInterface, SetsInterface, StreamsInterface}, prelude::RedisErrorKind, @@ -46,7 +46,6 @@ impl super::RedisConnectionPool { false, ) .await - .into_report() .change_context(errors::RedisError::SetFailed) } @@ -61,7 +60,6 @@ impl super::RedisConnectionPool { self.pool .msetnx(value) .await - .into_report() .change_context(errors::RedisError::SetFailed) } @@ -121,7 +119,6 @@ impl super::RedisConnectionPool { false, ) .await - .into_report() .change_context(errors::RedisError::SetExFailed) } @@ -133,7 +130,6 @@ impl super::RedisConnectionPool { self.pool .get(key) .await - .into_report() .change_context(errors::RedisError::GetFailed) } @@ -145,7 +141,6 @@ impl super::RedisConnectionPool { self.pool .exists(key) .await - .into_report() .change_context(errors::RedisError::GetFailed) } @@ -172,7 +167,6 @@ impl super::RedisConnectionPool { self.pool .del(key) .await - .into_report() .change_context(errors::RedisError::DeleteFailed) } @@ -190,7 +184,6 @@ impl super::RedisConnectionPool { self.pool .set(key, value, Some(Expiration::EX(seconds)), None, false) .await - .into_report() .change_context(errors::RedisError::SetExFailed) } @@ -216,7 +209,6 @@ impl super::RedisConnectionPool { false, ) .await - .into_report() .change_context(errors::RedisError::SetFailed) } @@ -229,7 +221,6 @@ impl super::RedisConnectionPool { self.pool .expire(key, seconds) .await - .into_report() .change_context(errors::RedisError::SetExpiryFailed) } @@ -242,7 +233,6 @@ impl super::RedisConnectionPool { self.pool .expire_at(key, timestamp) .await - .into_report() .change_context(errors::RedisError::SetExpiryFailed) } @@ -261,7 +251,6 @@ impl super::RedisConnectionPool { .pool .hset(key, values) .await - .into_report() .change_context(errors::RedisError::SetHashFailed); // setting expiry for the key output @@ -287,7 +276,6 @@ impl super::RedisConnectionPool { .pool .hsetnx(key, field, value) .await - .into_report() .change_context(errors::RedisError::SetHashFieldFailed); output @@ -330,7 +318,6 @@ impl super::RedisConnectionPool { self.pool .mget(keys) .await - .into_report() .change_context(errors::RedisError::GetFailed) } @@ -441,7 +428,6 @@ impl super::RedisConnectionPool { self.pool .hget(key, field) .await - .into_report() .change_context(errors::RedisError::GetHashFieldFailed) } @@ -479,7 +465,6 @@ impl super::RedisConnectionPool { self.pool .sadd(key, members) .await - .into_report() .change_context(errors::RedisError::SetAddMembersFailed) } @@ -497,7 +482,6 @@ impl super::RedisConnectionPool { self.pool .xadd(stream, false, None, entry_id, fields) .await - .into_report() .change_context(errors::RedisError::StreamAppendFailed) } @@ -513,7 +497,6 @@ impl super::RedisConnectionPool { self.pool .xdel(stream, ids) .await - .into_report() .change_context(errors::RedisError::StreamDeleteFailed) } @@ -530,7 +513,6 @@ impl super::RedisConnectionPool { self.pool .xtrim(stream, xcap) .await - .into_report() .change_context(errors::RedisError::StreamTrimFailed) } @@ -547,7 +529,6 @@ impl super::RedisConnectionPool { self.pool .xack(stream, group, ids) .await - .into_report() .change_context(errors::RedisError::StreamAcknowledgeFailed) } @@ -559,7 +540,6 @@ impl super::RedisConnectionPool { self.pool .xlen(stream) .await - .into_report() .change_context(errors::RedisError::GetLengthFailed) } @@ -582,12 +562,11 @@ impl super::RedisConnectionPool { ids, ) .await - .into_report() - .map_err(|err| match err.current_context().kind() { + .map_err(|err| match err.kind() { RedisErrorKind::NotFound | RedisErrorKind::Parse => { - err.change_context(errors::RedisError::StreamEmptyOrNotAvailable) + report!(err).change_context(errors::RedisError::StreamEmptyOrNotAvailable) } - _ => err.change_context(errors::RedisError::StreamReadFailed), + _ => report!(err).change_context(errors::RedisError::StreamReadFailed), }) } @@ -612,12 +591,11 @@ impl super::RedisConnectionPool { } None => self.pool.xread_map(count, block, streams, ids).await, } - .into_report() - .map_err(|err| match err.current_context().kind() { + .map_err(|err| match err.kind() { RedisErrorKind::NotFound | RedisErrorKind::Parse => { - err.change_context(errors::RedisError::StreamEmptyOrNotAvailable) + report!(err).change_context(errors::RedisError::StreamEmptyOrNotAvailable) } - _ => err.change_context(errors::RedisError::StreamReadFailed), + _ => report!(err).change_context(errors::RedisError::StreamReadFailed), }) } @@ -641,7 +619,6 @@ impl super::RedisConnectionPool { self.pool .xgroup_create(stream, group, id, true) .await - .into_report() .change_context(errors::RedisError::ConsumerGroupCreateFailed) } @@ -654,7 +631,6 @@ impl super::RedisConnectionPool { self.pool .xgroup_destroy(stream, group) .await - .into_report() .change_context(errors::RedisError::ConsumerGroupDestroyFailed) } @@ -669,7 +645,6 @@ impl super::RedisConnectionPool { self.pool .xgroup_delconsumer(stream, group, consumer) .await - .into_report() .change_context(errors::RedisError::ConsumerGroupRemoveConsumerFailed) } @@ -683,7 +658,6 @@ impl super::RedisConnectionPool { self.pool .xgroup_setid(stream, group, id) .await - .into_report() .change_context(errors::RedisError::ConsumerGroupSetIdFailed) } @@ -714,7 +688,6 @@ impl super::RedisConnectionPool { false, ) .await - .into_report() .change_context(errors::RedisError::ConsumerGroupClaimFailed) } } diff --git a/crates/redis_interface/src/lib.rs b/crates/redis_interface/src/lib.rs index b46e4aec191..0ab1ea394c9 100644 --- a/crates/redis_interface/src/lib.rs +++ b/crates/redis_interface/src/lib.rs @@ -23,7 +23,7 @@ pub mod types; use std::sync::{atomic, Arc}; use common_utils::errors::CustomResult; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; pub use fred::interfaces::PubsubInterface; use fred::{interfaces::ClientLike, prelude::EventInterface}; use router_env::logger; @@ -61,7 +61,6 @@ impl RedisClient { client .wait_for_connect() .await - .into_report() .change_context(errors::RedisError::RedisConnectionError)?; Ok(Self { inner: client }) } @@ -83,7 +82,6 @@ impl SubscriberClient { client .wait_for_connect() .await - .into_report() .change_context(errors::RedisError::RedisConnectionError)?; Ok(Self { inner: client }) } @@ -118,7 +116,6 @@ impl RedisConnectionPool { ), }; let mut config = fred::types::RedisConfig::from_url(&redis_connection_url) - .into_report() .change_context(errors::RedisError::RedisConnectionError)?; let perf = fred::types::PerformanceConfig { @@ -160,13 +157,11 @@ impl RedisConnectionPool { Some(reconnect_policy), conf.pool_size, ) - .into_report() .change_context(errors::RedisError::RedisConnectionError)?; pool.connect(); pool.wait_for_connect() .await - .into_report() .change_context(errors::RedisError::RedisConnectionError)?; let config = RedisConfig::from(conf); diff --git a/crates/redis_interface/src/types.rs b/crates/redis_interface/src/types.rs index cb883fc1693..6469df50778 100644 --- a/crates/redis_interface/src/types.rs +++ b/crates/redis_interface/src/types.rs @@ -4,7 +4,6 @@ //! use common_utils::errors::CustomResult; -use error_stack::IntoReport; use fred::types::RedisValue as FredRedisValue; use crate::errors; @@ -69,14 +68,12 @@ impl RedisSettings { Err(errors::RedisError::InvalidConfiguration( "Redis `host` must be specified".into(), )) - .into_report() })?; when(self.cluster_enabled && self.cluster_urls.is_empty(), || { Err(errors::RedisError::InvalidConfiguration( "Redis `cluster_urls` must be specified if `cluster_enabled` is `true`".into(), )) - .into_report() })?; when( @@ -84,8 +81,8 @@ impl RedisSettings { || { Err(errors::RedisError::InvalidConfiguration( "Unresponsive timeout cannot be greater than the command timeout".into(), - )) - .into_report() + ) + .into()) }, ) } diff --git a/crates/router/Cargo.toml b/crates/router/Cargo.toml index df3097d9e57..288e2001876 100644 --- a/crates/router/Cargo.toml +++ b/crates/router/Cargo.toml @@ -56,7 +56,7 @@ diesel = { version = "2.1.0", features = ["postgres"] } digest = "0.9" dyn-clone = "1.0.11" encoding_rs = "0.8.32" -error-stack = "0.3.1" +error-stack = "0.4.1" futures = "0.3.28" hex = "0.4.3" http = "0.2.9" diff --git a/crates/router/src/compatibility/stripe/payment_intents/types.rs b/crates/router/src/compatibility/stripe/payment_intents/types.rs index a74f16cee79..5a26c5e2615 100644 --- a/crates/router/src/compatibility/stripe/payment_intents/types.rs +++ b/crates/router/src/compatibility/stripe/payment_intents/types.rs @@ -7,7 +7,7 @@ use common_utils::{ ext_traits::StringExt, pii::{IpAddress, SecretSerdeValue, UpiVpaMaskingStrategy}, }; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use serde::{Deserialize, Serialize}; use time::PrimitiveDateTime; @@ -298,7 +298,6 @@ impl TryFrom for payments::PaymentsRequest { }) .map(|r| { serde_json::to_value(r) - .into_report() .change_context(errors::ApiErrorResponse::InternalServerError) .attach_printable("converting to routing failed") }) @@ -308,7 +307,6 @@ impl TryFrom for payments::PaymentsRequest { .receipt_ipaddress .map(|ip| std::net::IpAddr::from_str(ip.as_str())) .transpose() - .into_report() .change_context(errors::ApiErrorResponse::InvalidDataFormat { field_name: "receipt_ipaddress".to_string(), expected_format: "127.0.0.1".to_string(), @@ -383,7 +381,6 @@ impl TryFrom for payments::PaymentsRequest { user_agent: item.user_agent, ..Default::default() }) - .into_report() .change_context(errors::ApiErrorResponse::InternalServerError) .attach_printable("convert to browser info failed")?, ), @@ -720,10 +717,12 @@ impl ForeignTryFrom<(Option, Option)> for Option, Option), ) -> errors::RouterResult { let currency = currency - .ok_or(errors::ApiErrorResponse::MissingRequiredField { - field_name: "currency", - }) - .into_report() + .ok_or( + errors::ApiErrorResponse::MissingRequiredField { + field_name: "currency", + } + .into(), + ) .and_then(|c| { c.to_uppercase().parse_enum("currency").change_context( errors::ApiErrorResponse::InvalidDataValue { diff --git a/crates/router/src/compatibility/stripe/setup_intents/types.rs b/crates/router/src/compatibility/stripe/setup_intents/types.rs index a05a8c241d0..6fb6b6c808b 100644 --- a/crates/router/src/compatibility/stripe/setup_intents/types.rs +++ b/crates/router/src/compatibility/stripe/setup_intents/types.rs @@ -2,7 +2,7 @@ use std::str::FromStr; use api_models::payments; use common_utils::{date_time, ext_traits::StringExt, pii as secret}; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use router_env::logger; use serde::{Deserialize, Serialize}; use serde_json::Value; @@ -201,7 +201,6 @@ impl TryFrom for payments::PaymentsRequest { }) .map(|r| { serde_json::to_value(r) - .into_report() .change_context(errors::ApiErrorResponse::InternalServerError) .attach_printable("converting to routing failed") }) @@ -210,7 +209,6 @@ impl TryFrom for payments::PaymentsRequest { .receipt_ipaddress .map(|ip| std::net::IpAddr::from_str(ip.as_str())) .transpose() - .into_report() .change_context(errors::ApiErrorResponse::InvalidDataFormat { field_name: "receipt_ipaddress".to_string(), expected_format: "127.0.0.1".to_string(), @@ -292,7 +290,6 @@ impl TryFrom for payments::PaymentsRequest { user_agent: item.user_agent, ..Default::default() }) - .into_report() .change_context(errors::ApiErrorResponse::InternalServerError) .attach_printable("convert to browser info failed")?, ), diff --git a/crates/router/src/compatibility/stripe/webhooks.rs b/crates/router/src/compatibility/stripe/webhooks.rs index 777c36f301d..77e2c85abb4 100644 --- a/crates/router/src/compatibility/stripe/webhooks.rs +++ b/crates/router/src/compatibility/stripe/webhooks.rs @@ -3,7 +3,7 @@ use api_models::{ webhooks::{self as api}, }; use common_utils::{crypto::SignMessage, date_time, ext_traits::Encode}; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use router_env::logger; use serde::Serialize; @@ -39,7 +39,6 @@ impl OutgoingWebhookType for StripeOutgoingWebhook { let payment_response_hash_key = payment_response_hash_key .ok_or(errors::WebhooksFlowError::MerchantConfigNotFound) - .into_report() .attach_printable("For stripe compatibility payment_response_hash_key is mandatory")?; let webhook_signature_payload = self diff --git a/crates/router/src/connection.rs b/crates/router/src/connection.rs index 6c10f95ea79..009149b7225 100644 --- a/crates/router/src/connection.rs +++ b/crates/router/src/connection.rs @@ -1,6 +1,6 @@ use bb8::PooledConnection; use diesel::PgConnection; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use storage_impl::errors as storage_errors; use crate::errors; @@ -45,7 +45,6 @@ pub async fn pg_connection_read( pool.get() .await - .into_report() .change_context(storage_errors::StorageError::DatabaseConnectionError) } @@ -60,6 +59,5 @@ pub async fn pg_connection_write( pool.get() .await - .into_report() .change_context(storage_errors::StorageError::DatabaseConnectionError) } diff --git a/crates/router/src/connector/aci.rs b/crates/router/src/connector/aci.rs index b20b27f0228..a6599405b4a 100644 --- a/crates/router/src/connector/aci.rs +++ b/crates/router/src/connector/aci.rs @@ -3,7 +3,7 @@ pub mod transformers; use std::fmt::Debug; use common_utils::request::RequestContent; -use error_stack::{IntoReport, ResultExt}; +use error_stack::{report, ResultExt}; use masking::PeekInterface; use transformers as aci; @@ -47,8 +47,7 @@ impl ConnectorCommon for Aci { &self, auth_type: &types::ConnectorAuthType, ) -> CustomResult)>, errors::ConnectorError> { - let auth: aci::AciAuthType = auth_type - .try_into() + let auth = aci::AciAuthType::try_from(auth_type) .change_context(errors::ConnectorError::FailedToObtainAuthType)?; Ok(vec![( headers::AUTHORIZATION.to_string(), @@ -575,7 +574,7 @@ impl api::IncomingWebhook for Aci { &self, _request: &api::IncomingWebhookRequestDetails<'_>, ) -> CustomResult { - Err(errors::ConnectorError::WebhooksNotImplemented).into_report() + Err(report!(errors::ConnectorError::WebhooksNotImplemented)) } fn get_webhook_event_type( @@ -589,6 +588,6 @@ impl api::IncomingWebhook for Aci { &self, _request: &api::IncomingWebhookRequestDetails<'_>, ) -> CustomResult, errors::ConnectorError> { - Err(errors::ConnectorError::WebhooksNotImplemented).into_report() + Err(report!(errors::ConnectorError::WebhooksNotImplemented)) } } diff --git a/crates/router/src/connector/adyen.rs b/crates/router/src/connector/adyen.rs index d79761da472..44e889ed9db 100644 --- a/crates/router/src/connector/adyen.rs +++ b/crates/router/src/connector/adyen.rs @@ -6,7 +6,7 @@ use api_models::{enums::PaymentMethodType, webhooks::IncomingWebhookEvent}; use base64::Engine; use common_utils::request::RequestContent; use diesel_models::{enums as storage_enums, enums}; -use error_stack::{IntoReport, ResultExt}; +use error_stack::{report, ResultExt}; use masking::ExposeInterface; use ring::hmac; use router_env::{instrument, tracing}; @@ -568,7 +568,6 @@ impl let adyen_redirection_type = serde_urlencoded::from_str::< transformers::AdyenRedirectRequestTypes, >(encoded_data.as_str()) - .into_report() .change_context(errors::ConnectorError::ResponseDeserializationFailed)?; let connector_req = match adyen_redirection_type { @@ -1649,8 +1648,7 @@ fn get_webhook_object_from_body( .drain(..) .next() // TODO: ParsingError doesn't seem to be an apt error for this case - .ok_or(errors::ParsingError::UnknownError) - .into_report()?; + .ok_or(errors::ParsingError::UnknownError)?; Ok(item_object.notification_request_item) } @@ -1729,7 +1727,6 @@ impl api::IncomingWebhook for Adyen { .change_context(errors::ConnectorError::WebhookSourceVerificationFailed)?; let raw_key = hex::decode(connector_webhook_secrets.secret) - .into_report() .change_context(errors::ConnectorError::WebhookVerificationSecretInvalid)?; let signing_key = hmac::Key::new(hmac::HMAC_SHA256, &raw_key); @@ -1773,7 +1770,7 @@ impl api::IncomingWebhook for Adyen { ), )); } - Err(errors::ConnectorError::WebhookReferenceIdNotFound).into_report() + Err(report!(errors::ConnectorError::WebhookReferenceIdNotFound)) } fn get_webhook_event_type( diff --git a/crates/router/src/connector/adyen/transformers.rs b/crates/router/src/connector/adyen/transformers.rs index e5fe5374c45..b301be7f577 100644 --- a/crates/router/src/connector/adyen/transformers.rs +++ b/crates/router/src/connector/adyen/transformers.rs @@ -3,7 +3,7 @@ use api_models::payouts::PayoutMethodData; use api_models::{enums, payments, webhooks}; use cards::CardNumber; use common_utils::{ext_traits::Encode, pii}; -use error_stack::{IntoReport, ResultExt}; +use error_stack::{report, ResultExt}; use masking::{ExposeInterface, PeekInterface}; use reqwest::Url; use serde::{Deserialize, Serialize}; @@ -294,7 +294,7 @@ impl ForeignTryFrom<(bool, AdyenWebhookStatus)> for storage_enums::AttemptStatus //If Unexpected Event is received, need to understand how it reached this point //Webhooks with Payment Events only should try to conume this resource object. AdyenWebhookStatus::UnexpectedEvent => { - Err(errors::ConnectorError::WebhookBodyDecodingFailed).into_report() + Err(report!(errors::ConnectorError::WebhookBodyDecodingFailed)) } } } diff --git a/crates/router/src/connector/airwallex.rs b/crates/router/src/connector/airwallex.rs index defc6a339fb..6a8f384e199 100644 --- a/crates/router/src/connector/airwallex.rs +++ b/crates/router/src/connector/airwallex.rs @@ -7,7 +7,7 @@ use common_utils::{ request::RequestContent, }; use diesel_models::enums; -use error_stack::{IntoReport, ResultExt}; +use error_stack::{report, ResultExt}; use masking::PeekInterface; use transformers as airwallex; @@ -223,12 +223,11 @@ impl ConnectorIntegration for AirwallexCompleteR .as_ref() .map(|data| serde_json::to_string(data.peek())) .transpose() - .into_report() .change_context(errors::ConnectorError::ResponseDeserializationFailed)? .map(Secret::new), }, diff --git a/crates/router/src/connector/authorizedotnet.rs b/crates/router/src/connector/authorizedotnet.rs index be02b4524f8..946fded930d 100644 --- a/crates/router/src/connector/authorizedotnet.rs +++ b/crates/router/src/connector/authorizedotnet.rs @@ -4,7 +4,7 @@ use std::fmt::Debug; use common_utils::{crypto, ext_traits::ByteSliceExt, request::RequestContent}; use diesel_models::enums; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use transformers as authorizedotnet; use crate::{ @@ -833,18 +833,13 @@ impl api::IncomingWebhook for Authorizedotnet { .to_str() .map(String::from) .map_err(|_| errors::ConnectorError::WebhookSignatureNotFound) - .into_report() }) - .ok_or(errors::ConnectorError::WebhookSignatureNotFound) - .into_report()?? + .ok_or(errors::ConnectorError::WebhookSignatureNotFound)?? .to_lowercase(); let (_, sig_value) = security_header .split_once('=') - .ok_or(errors::ConnectorError::WebhookSourceVerificationFailed) - .into_report()?; - hex::decode(sig_value) - .into_report() - .change_context(errors::ConnectorError::WebhookSignatureNotFound) + .ok_or(errors::ConnectorError::WebhookSourceVerificationFailed)?; + hex::decode(sig_value).change_context(errors::ConnectorError::WebhookSignatureNotFound) } fn get_webhook_source_verification_message( diff --git a/crates/router/src/connector/authorizedotnet/transformers.rs b/crates/router/src/connector/authorizedotnet/transformers.rs index 4a79b179b84..2e5a9f3bbcb 100644 --- a/crates/router/src/connector/authorizedotnet/transformers.rs +++ b/crates/router/src/connector/authorizedotnet/transformers.rs @@ -2,7 +2,7 @@ use common_utils::{ errors::CustomResult, ext_traits::{Encode, ValueExt}, }; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use masking::{ExposeInterface, PeekInterface, Secret, StrongSecret}; use serde::{Deserialize, Serialize}; @@ -1395,7 +1395,6 @@ impl TryFrom<&AuthorizedotnetRouterData<&types::PaymentsCompleteAuthorizeRouterD .ok_or(errors::ConnectorError::ResponseDeserializationFailed)?; let payer_id: Secret = serde_urlencoded::from_str::(params.peek()) - .into_report() .change_context(errors::ConnectorError::ResponseDeserializationFailed)? .payer_id; let transaction_type = match item.router_data.request.capture_method { diff --git a/crates/router/src/connector/bambora.rs b/crates/router/src/connector/bambora.rs index d453677deb6..a9bfc54313d 100644 --- a/crates/router/src/connector/bambora.rs +++ b/crates/router/src/connector/bambora.rs @@ -4,7 +4,7 @@ use std::fmt::Debug; use common_utils::request::RequestContent; use diesel_models::enums; -use error_stack::{IntoReport, ResultExt}; +use error_stack::{report, ResultExt}; use transformers as bambora; use super::utils::RefundsRequestData; @@ -74,8 +74,7 @@ impl ConnectorCommon for Bambora { &self, auth_type: &types::ConnectorAuthType, ) -> CustomResult)>, errors::ConnectorError> { - let auth: bambora::BamboraAuthType = auth_type - .try_into() + let auth = bambora::BamboraAuthType::try_from(auth_type) .change_context(errors::ConnectorError::FailedToObtainAuthType)?; Ok(vec![( headers::AUTHORIZATION.to_string(), @@ -607,7 +606,7 @@ impl ConnectorIntegration, ) -> CustomResult { - Err(errors::ConnectorError::WebhooksNotImplemented).into_report() + Err(report!(errors::ConnectorError::WebhooksNotImplemented)) } fn get_webhook_event_type( @@ -718,7 +717,7 @@ impl api::IncomingWebhook for Bambora { &self, _request: &api::IncomingWebhookRequestDetails<'_>, ) -> CustomResult, errors::ConnectorError> { - Err(errors::ConnectorError::WebhooksNotImplemented).into_report() + Err(report!(errors::ConnectorError::WebhooksNotImplemented)) } } diff --git a/crates/router/src/connector/bambora/transformers.rs b/crates/router/src/connector/bambora/transformers.rs index c47b0718287..40c3219d353 100644 --- a/crates/router/src/connector/bambora/transformers.rs +++ b/crates/router/src/connector/bambora/transformers.rs @@ -1,6 +1,6 @@ use base64::Engine; use common_utils::{ext_traits::ValueExt, pii::IpAddress}; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use masking::{ExposeInterface, PeekInterface, Secret}; use serde::{Deserialize, Deserializer, Serialize}; @@ -239,7 +239,6 @@ impl serde_json::to_value(BamboraMeta { three_d_session_data: response.three_d_session_data.expose(), }) - .into_report() .change_context(errors::ConnectorError::ResponseHandlingFailed)?, ), network_txn_id: None, diff --git a/crates/router/src/connector/bankofamerica.rs b/crates/router/src/connector/bankofamerica.rs index aac441201eb..15c19622bc9 100644 --- a/crates/router/src/connector/bankofamerica.rs +++ b/crates/router/src/connector/bankofamerica.rs @@ -5,7 +5,7 @@ use std::fmt::Debug; use base64::Engine; use common_utils::request::RequestContent; use diesel_models::enums; -use error_stack::{IntoReport, ResultExt}; +use error_stack::{report, ResultExt}; use masking::{ExposeInterface, PeekInterface}; use ring::{digest, hmac}; use time::OffsetDateTime; @@ -87,7 +87,6 @@ impl Bankofamerica { ); let key_value = consts::BASE64_ENGINE .decode(api_secret.expose()) - .into_report() .change_context(errors::ConnectorError::InvalidConnectorConfig { config: "connector_account_details.api_secret", })?; @@ -129,9 +128,8 @@ where let auth = bankofamerica::BankOfAmericaAuthType::try_from(&req.connector_auth_type)?; let merchant_account = auth.merchant_account.clone(); let base_url = connectors.bankofamerica.base_url.as_str(); - let boa_host = Url::parse(base_url) - .into_report() - .change_context(errors::ConnectorError::RequestEncodingFailed)?; + let boa_host = + Url::parse(base_url).change_context(errors::ConnectorError::RequestEncodingFailed)?; let host = boa_host .host_str() .ok_or(errors::ConnectorError::RequestEncodingFailed)?; @@ -1175,20 +1173,20 @@ impl api::IncomingWebhook for Bankofamerica { &self, _request: &api::IncomingWebhookRequestDetails<'_>, ) -> CustomResult { - Err(errors::ConnectorError::WebhooksNotImplemented).into_report() + Err(report!(errors::ConnectorError::WebhooksNotImplemented)) } fn get_webhook_event_type( &self, _request: &api::IncomingWebhookRequestDetails<'_>, ) -> CustomResult { - Err(errors::ConnectorError::WebhooksNotImplemented).into_report() + Err(report!(errors::ConnectorError::WebhooksNotImplemented)) } fn get_webhook_resource_object( &self, _request: &api::IncomingWebhookRequestDetails<'_>, ) -> CustomResult, errors::ConnectorError> { - Err(errors::ConnectorError::WebhooksNotImplemented).into_report() + Err(report!(errors::ConnectorError::WebhooksNotImplemented)) } } diff --git a/crates/router/src/connector/bankofamerica/transformers.rs b/crates/router/src/connector/bankofamerica/transformers.rs index b4b8ce87ec8..c5a4f0b317a 100644 --- a/crates/router/src/connector/bankofamerica/transformers.rs +++ b/crates/router/src/connector/bankofamerica/transformers.rs @@ -1,7 +1,7 @@ use api_models::payments; use base64::Engine; use common_utils::{ext_traits::ValueExt, pii}; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use masking::{ExposeInterface, PeekInterface, Secret}; use serde::{Deserialize, Serialize}; use serde_json::Value; @@ -1500,7 +1500,6 @@ impl .consumer_authentication_information .validate_response, ) - .into_report() .change_context(errors::ConnectorError::ResponseHandlingFailed)?; Ok(Self { status, diff --git a/crates/router/src/connector/billwerk.rs b/crates/router/src/connector/billwerk.rs index c7d81e06c32..154b729abc9 100644 --- a/crates/router/src/connector/billwerk.rs +++ b/crates/router/src/connector/billwerk.rs @@ -2,7 +2,7 @@ pub mod transformers; use std::fmt::Debug; -use error_stack::{IntoReport, ResultExt}; +use error_stack::{report, ResultExt}; use masking::ExposeInterface; use transformers as billwerk; @@ -542,20 +542,20 @@ impl api::IncomingWebhook for Billwerk { &self, _request: &api::IncomingWebhookRequestDetails<'_>, ) -> CustomResult { - Err(errors::ConnectorError::WebhooksNotImplemented).into_report() + Err(report!(errors::ConnectorError::WebhooksNotImplemented)) } fn get_webhook_event_type( &self, _request: &api::IncomingWebhookRequestDetails<'_>, ) -> CustomResult { - Err(errors::ConnectorError::WebhooksNotImplemented).into_report() + Err(report!(errors::ConnectorError::WebhooksNotImplemented)) } fn get_webhook_resource_object( &self, _request: &api::IncomingWebhookRequestDetails<'_>, ) -> CustomResult, errors::ConnectorError> { - Err(errors::ConnectorError::WebhooksNotImplemented).into_report() + Err(report!(errors::ConnectorError::WebhooksNotImplemented)) } } diff --git a/crates/router/src/connector/bluesnap.rs b/crates/router/src/connector/bluesnap.rs index 71e140ca074..e32ebfc6f45 100644 --- a/crates/router/src/connector/bluesnap.rs +++ b/crates/router/src/connector/bluesnap.rs @@ -9,7 +9,7 @@ use common_utils::{ request::RequestContent, }; use diesel_models::enums; -use error_stack::{IntoReport, ResultExt}; +use error_stack::{report, ResultExt}; use masking::PeekInterface; use transformers as bluesnap; @@ -83,8 +83,7 @@ impl ConnectorCommon for Bluesnap { &self, auth_type: &types::ConnectorAuthType, ) -> CustomResult)>, errors::ConnectorError> { - let auth: bluesnap::BluesnapAuthType = auth_type - .try_into() + let auth = bluesnap::BluesnapAuthType::try_from(auth_type) .change_context(errors::ConnectorError::FailedToObtainAuthType)?; let encoded_api_key = consts::BASE64_ENGINE.encode(format!("{}:{}", auth.key1.peek(), auth.api_key.peek())); @@ -195,9 +194,9 @@ impl ConnectorValidation for Bluesnap { return Err( errors::ConnectorError::MissingConnectorRelatedTransactionID { id: "connector_transaction_id".to_string(), - }, - ) - .into_report(); + } + .into(), + ); } // if connector_transaction_id is present, psync can be made if data @@ -1051,7 +1050,6 @@ impl api::IncomingWebhook for Bluesnap { connector_utils::get_header_key_value("bls-signature", request.headers)?; hex::decode(security_header) - .into_report() .change_context(errors::ConnectorError::WebhookSignatureNotFound) } fn get_webhook_source_verification_message( @@ -1071,7 +1069,6 @@ impl api::IncomingWebhook for Bluesnap { ) -> CustomResult { let webhook_body: bluesnap::BluesnapWebhookBody = serde_urlencoded::from_bytes(request.body) - .into_report() .change_context(errors::ConnectorError::WebhookReferenceIdNotFound)?; match webhook_body.transaction_type { bluesnap::BluesnapWebhookEvents::Decline @@ -1103,7 +1100,7 @@ impl api::IncomingWebhook for Bluesnap { )) } bluesnap::BluesnapWebhookEvents::Unknown => { - Err(errors::ConnectorError::WebhookReferenceIdNotFound).into_report() + Err(report!(errors::ConnectorError::WebhookReferenceIdNotFound)) } } } @@ -1114,7 +1111,6 @@ impl api::IncomingWebhook for Bluesnap { ) -> CustomResult { let details: bluesnap::BluesnapWebhookObjectEventType = serde_urlencoded::from_bytes(request.body) - .into_report() .change_context(errors::ConnectorError::WebhookEventTypeNotFound)?; api::IncomingWebhookEvent::try_from(details) } @@ -1125,7 +1121,6 @@ impl api::IncomingWebhook for Bluesnap { ) -> CustomResult { let dispute_details: bluesnap::BluesnapDisputeWebhookBody = serde_urlencoded::from_bytes(request.body) - .into_report() .change_context(errors::ConnectorError::WebhookBodyDecodingFailed)?; Ok(api::disputes::DisputePayload { amount: connector_utils::to_currency_lower_unit( @@ -1150,7 +1145,6 @@ impl api::IncomingWebhook for Bluesnap { ) -> CustomResult, errors::ConnectorError> { let resource: bluesnap::BluesnapWebhookObjectResource = serde_urlencoded::from_bytes(request.body) - .into_report() .change_context(errors::ConnectorError::WebhookResourceObjectNotFound)?; Ok(Box::new(resource)) diff --git a/crates/router/src/connector/bluesnap/transformers.rs b/crates/router/src/connector/bluesnap/transformers.rs index a48e38705c4..e22d27e4b83 100644 --- a/crates/router/src/connector/bluesnap/transformers.rs +++ b/crates/router/src/connector/bluesnap/transformers.rs @@ -7,7 +7,7 @@ use common_utils::{ ext_traits::{ByteSliceExt, StringExt, ValueExt}, pii::Email, }; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use masking::{ExposeInterface, PeekInterface}; use serde::{Deserialize, Serialize}; use serde_json::Value; @@ -249,8 +249,8 @@ impl TryFrom<&BluesnapRouterData<&types::PaymentsAuthorizeRouterData>> | payments::PaymentMethodData::CardToken(_) => { Err(errors::ConnectorError::NotImplemented( "Selected payment method via Token flow through bluesnap".to_string(), - )) - .into_report() + ) + .into()) } } } @@ -496,7 +496,6 @@ impl TryFrom for Value { BluesnapWebhookEvents::Chargeback | BluesnapWebhookEvents::ChargebackStatusChanged => { //It won't be consumed in dispute flow, so currently does not hold any significance return serde_json::to_value(details) - .into_report() .change_context(errors::ConnectorError::WebhookBodyDecodingFailed); } BluesnapWebhookEvents::Refund => Ok(( @@ -1082,7 +1080,7 @@ impl TryFrom for Value { .ok_or(errors::ConnectorError::WebhookResourceObjectNotFound)?, )), BluesnapWebhookEvents::Unknown => { - Err(errors::ConnectorError::WebhookResourceObjectNotFound).into_report() + Err(errors::ConnectorError::WebhookResourceObjectNotFound) } }?; let sync_struct = BluesnapPaymentsResponse { @@ -1095,7 +1093,6 @@ impl TryFrom for Value { card_transaction_type, }; serde_json::to_value(sync_struct) - .into_report() .change_context(errors::ConnectorError::WebhookBodyDecodingFailed) } } diff --git a/crates/router/src/connector/boku.rs b/crates/router/src/connector/boku.rs index b3e26430924..7c456d2ec1c 100644 --- a/crates/router/src/connector/boku.rs +++ b/crates/router/src/connector/boku.rs @@ -3,7 +3,7 @@ use std::fmt::Debug; use common_utils::{ext_traits::XmlExt, request::RequestContent}; use diesel_models::enums; -use error_stack::{IntoReport, Report, ResultExt}; +use error_stack::{report, Report, ResultExt}; use masking::{ExposeInterface, PeekInterface, Secret, WithType}; use ring::hmac; use roxmltree; @@ -263,12 +263,10 @@ impl ConnectorIntegration CustomResult { let response_data = String::from_utf8(res.response.to_vec()) - .into_report() .change_context(errors::ConnectorError::ResponseDeserializationFailed)?; let response = response_data .parse_xml::() - .into_report() .change_context(errors::ConnectorError::ResponseDeserializationFailed)?; event_builder.map(|i| i.set_response_body(&response)); router_env::logger::info!(connector_response=?response); @@ -350,12 +348,10 @@ impl ConnectorIntegration CustomResult { let response_data = String::from_utf8(res.response.to_vec()) - .into_report() .change_context(errors::ConnectorError::ResponseDeserializationFailed)?; let response = response_data .parse_xml::() - .into_report() .change_context(errors::ConnectorError::ResponseDeserializationFailed)?; event_builder.map(|i| i.set_response_body(&response)); router_env::logger::info!(connector_response=?response); @@ -433,12 +429,10 @@ impl ConnectorIntegration CustomResult { let response_data = String::from_utf8(res.response.to_vec()) - .into_report() .change_context(errors::ConnectorError::ResponseDeserializationFailed)?; let response = response_data .parse_xml::() - .into_report() .change_context(errors::ConnectorError::ResponseDeserializationFailed)?; event_builder.map(|i| i.set_response_body(&response)); router_env::logger::info!(connector_response=?response); @@ -634,21 +628,21 @@ impl api::IncomingWebhook for Boku { &self, _request: &api::IncomingWebhookRequestDetails<'_>, ) -> CustomResult { - Err(errors::ConnectorError::WebhooksNotImplemented).into_report() + Err(report!(errors::ConnectorError::WebhooksNotImplemented)) } fn get_webhook_event_type( &self, _request: &api::IncomingWebhookRequestDetails<'_>, ) -> CustomResult { - Err(errors::ConnectorError::WebhooksNotImplemented).into_report() + Err(report!(errors::ConnectorError::WebhooksNotImplemented)) } fn get_webhook_resource_object( &self, _request: &api::IncomingWebhookRequestDetails<'_>, ) -> CustomResult, errors::ConnectorError> { - Err(errors::ConnectorError::WebhooksNotImplemented).into_report() + Err(report!(errors::ConnectorError::WebhooksNotImplemented)) } } @@ -675,7 +669,6 @@ fn get_xml_deserialized( ); let response_data = String::from_utf8(res.response.to_vec()) - .into_report() .change_context(errors::ConnectorError::ResponseDeserializationFailed)?; event_builder.map(|i| i.set_error_response_body(&response_data)); diff --git a/crates/router/src/connector/braintree.rs b/crates/router/src/connector/braintree.rs index b080db1df63..41133e3f670 100644 --- a/crates/router/src/connector/braintree.rs +++ b/crates/router/src/connector/braintree.rs @@ -6,7 +6,7 @@ use api_models::webhooks::IncomingWebhookEvent; use base64::Engine; use common_utils::{crypto, ext_traits::XmlExt, request::RequestContent}; use diesel_models::enums; -use error_stack::{IntoReport, Report, ResultExt}; +use error_stack::{report, Report, ResultExt}; use masking::{ExposeInterface, PeekInterface}; use ring::hmac; use sha1::{Digest, Sha1}; @@ -92,8 +92,7 @@ impl ConnectorCommon for Braintree { &self, auth_type: &types::ConnectorAuthType, ) -> CustomResult)>, errors::ConnectorError> { - let auth: braintree::BraintreeAuthType = auth_type - .try_into() + let auth = braintree::BraintreeAuthType::try_from(auth_type) .change_context(errors::ConnectorError::FailedToObtainAuthType)?; Ok(vec![( headers::AUTHORIZATION.to_string(), @@ -631,7 +630,7 @@ impl ConnectorIntegration Err(errors::ConnectorError::RequestEncodingFailed).into_report(), + false => Err(report!(errors::ConnectorError::RequestEncodingFailed)), } } @@ -978,7 +977,7 @@ impl ConnectorIntegration Err(errors::ConnectorError::RequestEncodingFailed).into_report(), + false => Err(report!(errors::ConnectorError::RequestEncodingFailed)), } } @@ -1242,7 +1241,7 @@ impl ConnectorIntegration Err(errors::ConnectorError::RequestEncodingFailed).into_report(), + false => Err(report!(errors::ConnectorError::RequestEncodingFailed)), } } @@ -1419,7 +1418,7 @@ impl api::IncomingWebhook for Braintree { dispute_data.transaction.id, ), )), - None => Err(errors::ConnectorError::WebhookReferenceIdNotFound).into_report(), + None => Err(report!(errors::ConnectorError::WebhookReferenceIdNotFound)), } } @@ -1471,7 +1470,6 @@ impl api::IncomingWebhook for Braintree { let currency = diesel_models::enums::Currency::from_str( dispute_data.currency_iso_code.as_str(), ) - .into_report() .change_context(errors::ConnectorError::WebhookBodyDecodingFailed)?; Ok(api::disputes::DisputePayload { amount: connector_utils::to_currency_lower_unit( @@ -1512,7 +1510,6 @@ fn get_webhook_object_from_body( body: &[u8], ) -> CustomResult { serde_urlencoded::from_bytes::(body) - .into_report() .change_context(errors::ParsingError::StructParseFailure( "BraintreeWebhookResponse", )) @@ -1523,16 +1520,13 @@ fn decode_webhook_payload( ) -> CustomResult { let decoded_response = consts::BASE64_ENGINE .decode(payload) - .into_report() .change_context(errors::ConnectorError::WebhookBodyDecodingFailed)?; let xml_response = String::from_utf8(decoded_response) - .into_report() .change_context(errors::ConnectorError::WebhookBodyDecodingFailed)?; xml_response .parse_xml::() - .into_report() .change_context(errors::ConnectorError::WebhookBodyDecodingFailed) } @@ -1547,7 +1541,7 @@ impl services::ConnectorRedirectResponse for Braintree { services::PaymentAction::PSync => match json_payload { Some(payload) => { let redirection_response:braintree_graphql_transformers::BraintreeRedirectionResponse = serde_json::from_value(payload) - .into_report() + .change_context( errors::ConnectorError::MissingConnectorRedirectionPayload { field_name: "redirection_response", diff --git a/crates/router/src/connector/braintree/braintree_graphql_transformers.rs b/crates/router/src/connector/braintree/braintree_graphql_transformers.rs index 78c4ee0e100..1f933392f2b 100644 --- a/crates/router/src/connector/braintree/braintree_graphql_transformers.rs +++ b/crates/router/src/connector/braintree/braintree_graphql_transformers.rs @@ -1,5 +1,5 @@ use common_utils::pii; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use masking::{ExposeInterface, Secret}; use serde::{Deserialize, Serialize}; use time::PrimitiveDateTime; @@ -1370,16 +1370,15 @@ impl TryFrom<&BraintreeRouterData<&types::PaymentsCompleteAuthorizeRouterData>> &item.router_data.request, )? .expose(); - let redirection_response: BraintreeRedirectionResponse = - serde_json::from_value(payload_data) - .into_report() - .change_context(errors::ConnectorError::MissingConnectorRedirectionPayload { - field_name: "redirection_response", - })?; + let redirection_response: BraintreeRedirectionResponse = serde_json::from_value( + payload_data, + ) + .change_context(errors::ConnectorError::MissingConnectorRedirectionPayload { + field_name: "redirection_response", + })?; let three_ds_data = serde_json::from_str::( &redirection_response.authentication_response, ) - .into_report() .change_context(errors::ConnectorError::MissingConnectorRedirectionPayload { field_name: "three_ds_data", })?; diff --git a/crates/router/src/connector/cashtocode.rs b/crates/router/src/connector/cashtocode.rs index 5dc80967893..279ad23259f 100644 --- a/crates/router/src/connector/cashtocode.rs +++ b/crates/router/src/connector/cashtocode.rs @@ -4,7 +4,7 @@ use std::fmt::Debug; use base64::Engine; use common_utils::request::RequestContent; use diesel_models::enums; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use masking::{PeekInterface, Secret}; use transformers as cashtocode; @@ -384,11 +384,9 @@ impl api::IncomingWebhook for Cashtocode { .change_context(errors::ConnectorError::WebhookSourceVerificationFailed)?; let secret_auth = String::from_utf8(connector_webhook_secrets.secret.to_vec()) - .into_report() .change_context(errors::ConnectorError::WebhookSourceVerificationFailed) .attach_printable("Could not convert secret to UTF-8")?; let signature_auth = String::from_utf8(signature.to_vec()) - .into_report() .change_context(errors::ConnectorError::WebhookSourceVerificationFailed) .attach_printable("Could not convert secret to UTF-8")?; Ok(signature_auth == secret_auth) diff --git a/crates/router/src/connector/cashtocode/transformers.rs b/crates/router/src/connector/cashtocode/transformers.rs index 6e930d5cb4b..525b19df001 100644 --- a/crates/router/src/connector/cashtocode/transformers.rs +++ b/crates/router/src/connector/cashtocode/transformers.rs @@ -2,7 +2,7 @@ use std::collections::HashMap; pub use common_utils::request::Method; use common_utils::{errors::CustomResult, ext_traits::ValueExt, pii::Email}; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use masking::Secret; use serde::{Deserialize, Serialize}; @@ -57,8 +57,7 @@ impl TryFrom<&types::PaymentsAuthorizeRouterData> for CashtocodePaymentsRequest &item.connector_auth_type, item.request.payment_method_type, item.request.currency, - ) - .into_report()?; + )?; match item.payment_method { diesel_models::enums::PaymentMethod::Reward => Ok(Self { amount: utils::to_currency_base_unit_asf64( diff --git a/crates/router/src/connector/checkout.rs b/crates/router/src/connector/checkout.rs index 30be1315e15..33a43b0a03c 100644 --- a/crates/router/src/connector/checkout.rs +++ b/crates/router/src/connector/checkout.rs @@ -8,7 +8,7 @@ use common_utils::{ request::RequestContent, }; use diesel_models::enums; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use masking::PeekInterface; use self::transformers as checkout; @@ -78,8 +78,7 @@ impl ConnectorCommon for Checkout { &self, auth_type: &types::ConnectorAuthType, ) -> CustomResult)>, errors::ConnectorError> { - let auth: checkout::CheckoutAuthType = auth_type - .try_into() + let auth = checkout::CheckoutAuthType::try_from(auth_type) .change_context(errors::ConnectorError::FailedToObtainAuthType)?; Ok(vec![( headers::AUTHORIZATION.to_string(), @@ -754,12 +753,11 @@ impl ConnectorIntegration CustomResult, errors::ConnectorError> { let signature = conn_utils::get_header_key_value("cko-signature", request.headers) .change_context(errors::ConnectorError::WebhookSignatureNotFound)?; - hex::decode(signature) - .into_report() - .change_context(errors::ConnectorError::WebhookSignatureNotFound) + hex::decode(signature).change_context(errors::ConnectorError::WebhookSignatureNotFound) } fn get_webhook_source_verification_message( &self, diff --git a/crates/router/src/connector/checkout/transformers.rs b/crates/router/src/connector/checkout/transformers.rs index 6328f98081d..1a031eaa7ca 100644 --- a/crates/router/src/connector/checkout/transformers.rs +++ b/crates/router/src/connector/checkout/transformers.rs @@ -1,5 +1,5 @@ use common_utils::{errors::CustomResult, ext_traits::ByteSliceExt}; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use masking::{ExposeInterface, Secret}; use serde::{Deserialize, Serialize}; use time::PrimitiveDateTime; @@ -1356,7 +1356,6 @@ pub fn construct_file_upload_request( .unwrap_or_default() )) .mime_str(request.file_type.as_ref()) - .into_report() .change_context(errors::ConnectorError::RequestEncodingFailed) .attach_printable("Failure in constructing file data")?; multipart = multipart.part("file", file_data); diff --git a/crates/router/src/connector/coinbase.rs b/crates/router/src/connector/coinbase.rs index 700731348fb..8bfbe8b695a 100644 --- a/crates/router/src/connector/coinbase.rs +++ b/crates/router/src/connector/coinbase.rs @@ -4,7 +4,7 @@ use std::fmt::Debug; use common_utils::{crypto, ext_traits::ByteSliceExt, request::RequestContent}; use diesel_models::enums; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use transformers as coinbase; use self::coinbase::CoinbaseWebhookDetails; @@ -394,7 +394,6 @@ impl api::IncomingWebhook for Coinbase { let base64_signature = utils::get_header_key_value("X-CC-Webhook-Signature", request.headers)?; hex::decode(base64_signature) - .into_report() .change_context(errors::ConnectorError::WebhookSourceVerificationFailed) } @@ -405,7 +404,6 @@ impl api::IncomingWebhook for Coinbase { _connector_webhook_secrets: &api_models::webhooks::ConnectorWebhookSecrets, ) -> CustomResult, errors::ConnectorError> { let message = std::str::from_utf8(request.body) - .into_report() .change_context(errors::ConnectorError::WebhookSourceVerificationFailed)?; Ok(message.to_string().into_bytes()) } diff --git a/crates/router/src/connector/cryptopay.rs b/crates/router/src/connector/cryptopay.rs index a3335b2e228..2f9c996eff4 100644 --- a/crates/router/src/connector/cryptopay.rs +++ b/crates/router/src/connector/cryptopay.rs @@ -9,7 +9,7 @@ use common_utils::{ ext_traits::ByteSliceExt, request::RequestContent, }; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use hex::encode; use masking::PeekInterface; use transformers as cryptopay; @@ -91,7 +91,6 @@ where let api_method = method.to_string(); let now = date_time::date_as_yyyymmddthhmmssmmmz() - .into_report() .change_context(errors::ConnectorError::RequestEncodingFailed)?; let date = format!("{}+00:00", now.split_at(now.len() - 5).0); @@ -425,7 +424,6 @@ impl api::IncomingWebhook for Cryptopay { let base64_signature = utils::get_header_key_value("X-Cryptopay-Signature", request.headers)?; hex::decode(base64_signature) - .into_report() .change_context(errors::ConnectorError::WebhookSourceVerificationFailed) } @@ -436,7 +434,6 @@ impl api::IncomingWebhook for Cryptopay { _connector_webhook_secrets: &api_models::webhooks::ConnectorWebhookSecrets, ) -> CustomResult, errors::ConnectorError> { let message = std::str::from_utf8(request.body) - .into_report() .change_context(errors::ConnectorError::WebhookSourceVerificationFailed)?; Ok(message.to_string().into_bytes()) } diff --git a/crates/router/src/connector/cybersource.rs b/crates/router/src/connector/cybersource.rs index e89810e79cf..5298420cde2 100644 --- a/crates/router/src/connector/cybersource.rs +++ b/crates/router/src/connector/cybersource.rs @@ -5,7 +5,7 @@ use std::fmt::Debug; use base64::Engine; use common_utils::request::RequestContent; use diesel_models::enums; -use error_stack::{IntoReport, ResultExt}; +use error_stack::{report, ResultExt}; use masking::{ExposeInterface, PeekInterface}; use ring::{digest, hmac}; use time::OffsetDateTime; @@ -79,7 +79,6 @@ impl Cybersource { ); let key_value = consts::BASE64_ENGINE .decode(api_secret.expose()) - .into_report() .change_context(errors::ConnectorError::InvalidConnectorConfig { config: "connector_account_details.api_secret", })?; @@ -230,9 +229,8 @@ where let auth = cybersource::CybersourceAuthType::try_from(&req.connector_auth_type)?; let merchant_account = auth.merchant_account.clone(); let base_url = connectors.cybersource.base_url.as_str(); - let cybersource_host = Url::parse(base_url) - .into_report() - .change_context(errors::ConnectorError::RequestEncodingFailed)?; + let cybersource_host = + Url::parse(base_url).change_context(errors::ConnectorError::RequestEncodingFailed)?; let host = cybersource_host .host_str() .ok_or(errors::ConnectorError::RequestEncodingFailed)?; @@ -448,7 +446,6 @@ impl } else { // If http_code != 204 || http_code != 4xx, we dont know any other response scenario yet. let response_value: serde_json::Value = serde_json::from_slice(&res.response) - .into_report() .change_context(errors::ConnectorError::ResponseHandlingFailed)?; let response_string = response_value.to_string(); @@ -1482,7 +1479,7 @@ impl api::IncomingWebhook for Cybersource { &self, _request: &api::IncomingWebhookRequestDetails<'_>, ) -> CustomResult { - Err(errors::ConnectorError::WebhooksNotImplemented).into_report() + Err(report!(errors::ConnectorError::WebhooksNotImplemented)) } fn get_webhook_event_type( @@ -1496,6 +1493,6 @@ impl api::IncomingWebhook for Cybersource { &self, _request: &api::IncomingWebhookRequestDetails<'_>, ) -> CustomResult, errors::ConnectorError> { - Err(errors::ConnectorError::WebhooksNotImplemented).into_report() + Err(report!(errors::ConnectorError::WebhooksNotImplemented)) } } diff --git a/crates/router/src/connector/cybersource/transformers.rs b/crates/router/src/connector/cybersource/transformers.rs index 19d5e177226..d58f51e1d78 100644 --- a/crates/router/src/connector/cybersource/transformers.rs +++ b/crates/router/src/connector/cybersource/transformers.rs @@ -2,7 +2,7 @@ use api_models::payments; use base64::Engine; use common_enums::FutureUsage; use common_utils::{ext_traits::ValueExt, pii}; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use masking::{ExposeInterface, PeekInterface, Secret}; use serde::{Deserialize, Serialize}; use serde_json::Value; @@ -2120,7 +2120,6 @@ impl .consumer_authentication_information .validate_response, ) - .into_report() .change_context(errors::ConnectorError::ResponseHandlingFailed)?; Ok(Self { status, diff --git a/crates/router/src/connector/dlocal.rs b/crates/router/src/connector/dlocal.rs index b158f239fdd..c92c6b8b854 100644 --- a/crates/router/src/connector/dlocal.rs +++ b/crates/router/src/connector/dlocal.rs @@ -8,7 +8,7 @@ use common_utils::{ request::RequestContent, }; use diesel_models::enums; -use error_stack::{IntoReport, ResultExt}; +use error_stack::{report, ResultExt}; use hex::encode; use masking::PeekInterface; use transformers as dlocal; @@ -61,7 +61,6 @@ where let dlocal_req = self.get_request_body(req, connectors)?; let date = date_time::date_as_yyyymmddthhmmssmmmz() - .into_report() .change_context(errors::ConnectorError::RequestEncodingFailed)?; let auth = dlocal::DlocalAuthType::try_from(&req.connector_auth_type)?; let sign_req: String = format!( @@ -275,12 +274,11 @@ impl ConnectorIntegration, ) -> CustomResult { - Err(errors::ConnectorError::WebhooksNotImplemented).into_report() + Err(report!(errors::ConnectorError::WebhooksNotImplemented)) } fn get_webhook_event_type( @@ -702,6 +696,6 @@ impl api::IncomingWebhook for Dlocal { &self, _request: &api::IncomingWebhookRequestDetails<'_>, ) -> CustomResult, errors::ConnectorError> { - Err(errors::ConnectorError::WebhooksNotImplemented).into_report() + Err(report!(errors::ConnectorError::WebhooksNotImplemented)) } } diff --git a/crates/router/src/connector/dummyconnector.rs b/crates/router/src/connector/dummyconnector.rs index 7889c4e4053..13a05578238 100644 --- a/crates/router/src/connector/dummyconnector.rs +++ b/crates/router/src/connector/dummyconnector.rs @@ -4,7 +4,7 @@ use std::fmt::Debug; use common_utils::request::RequestContent; use diesel_models::enums; -use error_stack::{IntoReport, ResultExt}; +use error_stack::{report, ResultExt}; use super::utils::RefundsRequestData; use crate::{ @@ -594,7 +594,7 @@ impl api::IncomingWebhook for DummyConnector { &self, _request: &api::IncomingWebhookRequestDetails<'_>, ) -> CustomResult { - Err(errors::ConnectorError::WebhooksNotImplemented).into_report() + Err(report!(errors::ConnectorError::WebhooksNotImplemented)) } fn get_webhook_event_type( @@ -608,6 +608,6 @@ impl api::IncomingWebhook for DummyConnector { &self, _request: &api::IncomingWebhookRequestDetails<'_>, ) -> CustomResult, errors::ConnectorError> { - Err(errors::ConnectorError::WebhooksNotImplemented).into_report() + Err(report!(errors::ConnectorError::WebhooksNotImplemented)) } } diff --git a/crates/router/src/connector/fiserv.rs b/crates/router/src/connector/fiserv.rs index fdd904ee737..75147fe780c 100644 --- a/crates/router/src/connector/fiserv.rs +++ b/crates/router/src/connector/fiserv.rs @@ -5,7 +5,7 @@ use std::fmt::Debug; use base64::Engine; use common_utils::request::RequestContent; use diesel_models::enums; -use error_stack::{IntoReport, ResultExt}; +use error_stack::{report, ResultExt}; use masking::{ExposeInterface, PeekInterface}; use ring::hmac; use time::OffsetDateTime; @@ -119,8 +119,7 @@ impl ConnectorCommon for Fiserv { &self, auth_type: &types::ConnectorAuthType, ) -> CustomResult)>, errors::ConnectorError> { - let auth: fiserv::FiservAuthType = auth_type - .try_into() + let auth = fiserv::FiservAuthType::try_from(auth_type) .change_context(errors::ConnectorError::FailedToObtainAuthType)?; Ok(vec![( headers::API_KEY.to_string(), @@ -305,12 +304,11 @@ impl ConnectorIntegration, ) -> CustomResult { - Err(errors::ConnectorError::WebhooksNotImplemented).into_report() + Err(report!(errors::ConnectorError::WebhooksNotImplemented)) } fn get_webhook_event_type( @@ -804,6 +797,6 @@ impl api::IncomingWebhook for Fiserv { &self, _request: &api::IncomingWebhookRequestDetails<'_>, ) -> CustomResult, errors::ConnectorError> { - Err(errors::ConnectorError::WebhooksNotImplemented).into_report() + Err(report!(errors::ConnectorError::WebhooksNotImplemented)) } } diff --git a/crates/router/src/connector/forte.rs b/crates/router/src/connector/forte.rs index 7cc3f9f9a4e..8b858e5553e 100644 --- a/crates/router/src/connector/forte.rs +++ b/crates/router/src/connector/forte.rs @@ -5,7 +5,7 @@ use std::fmt::Debug; use base64::Engine; use common_utils::request::RequestContent; use diesel_models::enums; -use error_stack::{IntoReport, ResultExt}; +use error_stack::{report, ResultExt}; use masking::PeekInterface; use transformers as forte; @@ -94,8 +94,7 @@ impl ConnectorCommon for Forte { &self, auth_type: &types::ConnectorAuthType, ) -> CustomResult)>, errors::ConnectorError> { - let auth: forte::ForteAuthType = auth_type - .try_into() + let auth = forte::ForteAuthType::try_from(auth_type) .change_context(errors::ConnectorError::FailedToObtainAuthType)?; let raw_basic_token = format!( "{}:{}", @@ -695,7 +694,7 @@ impl api::IncomingWebhook for Forte { &self, _request: &api::IncomingWebhookRequestDetails<'_>, ) -> CustomResult { - Err(errors::ConnectorError::WebhooksNotImplemented).into_report() + Err(report!(errors::ConnectorError::WebhooksNotImplemented)) } fn get_webhook_event_type( @@ -709,6 +708,6 @@ impl api::IncomingWebhook for Forte { &self, _request: &api::IncomingWebhookRequestDetails<'_>, ) -> CustomResult, errors::ConnectorError> { - Err(errors::ConnectorError::WebhooksNotImplemented).into_report() + Err(report!(errors::ConnectorError::WebhooksNotImplemented)) } } diff --git a/crates/router/src/connector/globalpay.rs b/crates/router/src/connector/globalpay.rs index d9123c516ec..447c0568dc1 100644 --- a/crates/router/src/connector/globalpay.rs +++ b/crates/router/src/connector/globalpay.rs @@ -7,7 +7,7 @@ use std::fmt::Debug; use ::common_utils::{errors::ReportSwitchExt, ext_traits::ByteSliceExt, request::RequestContent}; use diesel_models::enums; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use masking::PeekInterface; use serde_json::Value; @@ -304,12 +304,11 @@ impl ConnectorIntegration CustomResult, errors::ConnectorError> { let payload: Value = request.body.parse_struct("GlobalpayWebhookBody").switch()?; let mut payload_str = serde_json::to_string(&payload) - .into_report() .change_context(errors::ConnectorError::WebhookBodyDecodingFailed)?; let sec = std::str::from_utf8(&connector_webhook_secrets.secret) - .into_report() .change_context(errors::ConnectorError::WebhookBodyDecodingFailed)?; payload_str.push_str(sec); Ok(payload_str.into_bytes()) @@ -967,13 +960,10 @@ impl api::IncomingWebhook for Globalpay { request: &api::IncomingWebhookRequestDetails<'_>, ) -> CustomResult, errors::ConnectorError> { let details = std::str::from_utf8(request.body) - .into_report() .change_context(errors::ConnectorError::WebhookBodyDecodingFailed)?; - Ok(Box::new( - serde_json::from_str(details) - .into_report() - .change_context(errors::ConnectorError::WebhookResourceObjectNotFound)?, - )) + Ok(Box::new(serde_json::from_str(details).change_context( + errors::ConnectorError::WebhookResourceObjectNotFound, + )?)) } } diff --git a/crates/router/src/connector/globalpay/transformers.rs b/crates/router/src/connector/globalpay/transformers.rs index 35987ae26b3..ae6f8d3966a 100644 --- a/crates/router/src/connector/globalpay/transformers.rs +++ b/crates/router/src/connector/globalpay/transformers.rs @@ -1,5 +1,5 @@ use common_utils::crypto::{self, GenerateDigest}; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use masking::{ExposeInterface, PeekInterface, Secret}; use rand::distributions::DistString; use serde::{Deserialize, Serialize}; @@ -265,9 +265,7 @@ impl }) .filter(|redirect_str| !redirect_str.is_empty()) .map(|url| { - Url::parse(url) - .into_report() - .change_context(errors::ConnectorError::FailedToObtainIntegrationUrl) + Url::parse(url).change_context(errors::ConnectorError::FailedToObtainIntegrationUrl) }) .transpose()?; let redirection_data = @@ -486,10 +484,7 @@ impl TryFrom<&api_models::payments::BankRedirectData> for PaymentMethodData { api_models::payments::BankRedirectData::Sofort { .. } => Ok(Self::Apm(requests::Apm { provider: Some(ApmProvider::Sofort), })), - _ => Err(errors::ConnectorError::NotImplemented( - "Payment method".to_string(), - )) - .into_report(), + _ => Err(errors::ConnectorError::NotImplemented("Payment method".to_string()).into()), } } } diff --git a/crates/router/src/connector/globepay.rs b/crates/router/src/connector/globepay.rs index d480e35cfc0..6570351f9e2 100644 --- a/crates/router/src/connector/globepay.rs +++ b/crates/router/src/connector/globepay.rs @@ -7,7 +7,7 @@ use common_utils::{ request::RequestContent, }; use diesel_models::enums; -use error_stack::{IntoReport, ResultExt}; +use error_stack::{report, ResultExt}; use hex::encode; use masking::ExposeInterface; use rand::distributions::DistString; @@ -532,20 +532,20 @@ impl api::IncomingWebhook for Globepay { &self, _request: &api::IncomingWebhookRequestDetails<'_>, ) -> CustomResult { - Err(errors::ConnectorError::WebhooksNotImplemented).into_report() + Err(report!(errors::ConnectorError::WebhooksNotImplemented)) } fn get_webhook_event_type( &self, _request: &api::IncomingWebhookRequestDetails<'_>, ) -> CustomResult { - Err(errors::ConnectorError::WebhooksNotImplemented).into_report() + Err(report!(errors::ConnectorError::WebhooksNotImplemented)) } fn get_webhook_resource_object( &self, _request: &api::IncomingWebhookRequestDetails<'_>, ) -> CustomResult, errors::ConnectorError> { - Err(errors::ConnectorError::WebhooksNotImplemented).into_report() + Err(report!(errors::ConnectorError::WebhooksNotImplemented)) } } diff --git a/crates/router/src/connector/gocardless.rs b/crates/router/src/connector/gocardless.rs index 806aec7dbeb..72007c5ba73 100644 --- a/crates/router/src/connector/gocardless.rs +++ b/crates/router/src/connector/gocardless.rs @@ -4,7 +4,7 @@ use std::fmt::Debug; use api_models::enums::enums; use common_utils::{crypto, ext_traits::ByteSliceExt, request::RequestContent}; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use masking::PeekInterface; use transformers as gocardless; @@ -738,14 +738,10 @@ impl api::IncomingWebhook for Gocardless { .to_str() .map(String::from) .map_err(|_| errors::ConnectorError::WebhookSignatureNotFound) - .into_report() }) - .ok_or(errors::ConnectorError::WebhookSignatureNotFound) - .into_report()??; + .ok_or(errors::ConnectorError::WebhookSignatureNotFound)??; - hex::decode(signature) - .into_report() - .change_context(errors::ConnectorError::WebhookSignatureNotFound) + hex::decode(signature).change_context(errors::ConnectorError::WebhookSignatureNotFound) } fn get_webhook_source_verification_message( diff --git a/crates/router/src/connector/helcim.rs b/crates/router/src/connector/helcim.rs index d1b9732cb17..a6305ef6366 100644 --- a/crates/router/src/connector/helcim.rs +++ b/crates/router/src/connector/helcim.rs @@ -4,7 +4,7 @@ use std::fmt::Debug; use common_utils::request::RequestContent; use diesel_models::enums; -use error_stack::{IntoReport, ResultExt}; +use error_stack::{report, ResultExt}; use masking::ExposeInterface; use transformers as helcim; @@ -787,20 +787,20 @@ impl api::IncomingWebhook for Helcim { &self, _request: &api::IncomingWebhookRequestDetails<'_>, ) -> CustomResult { - Err(errors::ConnectorError::WebhooksNotImplemented).into_report() + Err(report!(errors::ConnectorError::WebhooksNotImplemented)) } fn get_webhook_event_type( &self, _request: &api::IncomingWebhookRequestDetails<'_>, ) -> CustomResult { - Err(errors::ConnectorError::WebhooksNotImplemented).into_report() + Err(report!(errors::ConnectorError::WebhooksNotImplemented)) } fn get_webhook_resource_object( &self, _request: &api::IncomingWebhookRequestDetails<'_>, ) -> CustomResult, errors::ConnectorError> { - Err(errors::ConnectorError::WebhooksNotImplemented).into_report() + Err(report!(errors::ConnectorError::WebhooksNotImplemented)) } } diff --git a/crates/router/src/connector/helcim/transformers.rs b/crates/router/src/connector/helcim/transformers.rs index fba46bd721f..66cb2666038 100644 --- a/crates/router/src/connector/helcim/transformers.rs +++ b/crates/router/src/connector/helcim/transformers.rs @@ -1,5 +1,5 @@ use common_utils::pii::{Email, IpAddress}; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use masking::Secret; use serde::{Deserialize, Serialize}; @@ -158,10 +158,9 @@ impl TryFrom<&types::SetupMandateRouterData> for HelcimVerifyRequest { fn try_from(item: &types::SetupMandateRouterData) -> Result { match item.request.payment_method_data.clone() { api::PaymentMethodData::Card(req_card) => Self::try_from((item, &req_card)), - api_models::payments::PaymentMethodData::BankTransfer(_) => Err( - errors::ConnectorError::NotImplemented("Payment Method".to_string()), - ) - .into_report(), + api_models::payments::PaymentMethodData::BankTransfer(_) => { + Err(errors::ConnectorError::NotImplemented("Payment Method".to_string()).into()) + } api_models::payments::PaymentMethodData::CardRedirect(_) | api_models::payments::PaymentMethodData::Wallet(_) | api_models::payments::PaymentMethodData::PayLater(_) @@ -260,10 +259,9 @@ impl TryFrom<&HelcimRouterData<&types::PaymentsAuthorizeRouterData>> for HelcimP ) -> Result { match item.router_data.request.payment_method_data.clone() { api::PaymentMethodData::Card(req_card) => Self::try_from((item, &req_card)), - api_models::payments::PaymentMethodData::BankTransfer(_) => Err( - errors::ConnectorError::NotImplemented("Payment Method".to_string()), - ) - .into_report(), + api_models::payments::PaymentMethodData::BankTransfer(_) => { + Err(errors::ConnectorError::NotImplemented("Payment Method".to_string()).into()) + } api_models::payments::PaymentMethodData::CardRedirect(_) | api_models::payments::PaymentMethodData::Wallet(_) | api_models::payments::PaymentMethodData::PayLater(_) @@ -541,7 +539,6 @@ impl TryFrom<&HelcimRouterData<&types::PaymentsCaptureRouterData>> for HelcimCap .request .connector_transaction_id .parse::() - .into_report() .change_context(errors::ConnectorError::RequestEncodingFailed)?, amount: item.amount, ip_address, @@ -605,7 +602,6 @@ impl TryFrom<&types::PaymentsCancelRouterData> for HelcimVoidRequest { .request .connector_transaction_id .parse::() - .into_report() .change_context(errors::ConnectorError::RequestEncodingFailed)?, ip_address, ecommerce: None, @@ -672,7 +668,6 @@ impl TryFrom<&HelcimRouterData<&types::RefundsRouterData>> for HelcimRefun .request .connector_transaction_id .parse::() - .into_report() .change_context(errors::ConnectorError::RequestEncodingFailed)?; let ip_address = item diff --git a/crates/router/src/connector/iatapay.rs b/crates/router/src/connector/iatapay.rs index c049520de28..9adf50d6f5e 100644 --- a/crates/router/src/connector/iatapay.rs +++ b/crates/router/src/connector/iatapay.rs @@ -4,7 +4,7 @@ use std::fmt::Debug; use base64::Engine; use common_utils::{crypto, ext_traits::ByteSliceExt, request::RequestContent}; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use masking::PeekInterface; use transformers as iatapay; @@ -652,7 +652,6 @@ impl api::IncomingWebhook for Iatapay { _connector_webhook_secrets: &api_models::webhooks::ConnectorWebhookSecrets, ) -> CustomResult, errors::ConnectorError> { let message = std::str::from_utf8(request.body) - .into_report() .change_context(errors::ConnectorError::WebhookSourceVerificationFailed)?; Ok(message.to_string().into_bytes()) } diff --git a/crates/router/src/connector/klarna.rs b/crates/router/src/connector/klarna.rs index 8b7ab0da7f2..91ef719e5e0 100644 --- a/crates/router/src/connector/klarna.rs +++ b/crates/router/src/connector/klarna.rs @@ -3,7 +3,7 @@ use std::fmt::Debug; use api_models::payments as api_payments; use common_utils::request::RequestContent; -use error_stack::{IntoReport, ResultExt}; +use error_stack::{report, ResultExt}; use transformers as klarna; use crate::{ @@ -50,8 +50,7 @@ impl ConnectorCommon for Klarna { &self, auth_type: &types::ConnectorAuthType, ) -> CustomResult)>, errors::ConnectorError> { - let auth: klarna::KlarnaAuthType = auth_type - .try_into() + let auth = klarna::KlarnaAuthType::try_from(auth_type) .change_context(errors::ConnectorError::FailedToObtainAuthType)?; Ok(vec![( headers::AUTHORIZATION.to_string(), @@ -532,7 +531,7 @@ impl api::IncomingWebhook for Klarna { &self, _request: &api::IncomingWebhookRequestDetails<'_>, ) -> CustomResult { - Err(errors::ConnectorError::WebhooksNotImplemented).into_report() + Err(report!(errors::ConnectorError::WebhooksNotImplemented)) } fn get_webhook_event_type( @@ -546,6 +545,6 @@ impl api::IncomingWebhook for Klarna { &self, _request: &api::IncomingWebhookRequestDetails<'_>, ) -> CustomResult, errors::ConnectorError> { - Err(errors::ConnectorError::WebhooksNotImplemented).into_report() + Err(report!(errors::ConnectorError::WebhooksNotImplemented)) } } diff --git a/crates/router/src/connector/mollie.rs b/crates/router/src/connector/mollie.rs index e6bbd688376..84014fd6d59 100644 --- a/crates/router/src/connector/mollie.rs +++ b/crates/router/src/connector/mollie.rs @@ -3,7 +3,7 @@ pub mod transformers; use std::fmt::Debug; use common_utils::request::RequestContent; -use error_stack::{IntoReport, ResultExt}; +use error_stack::{report, ResultExt}; use masking::PeekInterface; use transformers as mollie; @@ -76,8 +76,7 @@ impl ConnectorCommon for Mollie { &self, auth_type: &types::ConnectorAuthType, ) -> CustomResult)>, errors::ConnectorError> { - let auth: mollie::MollieAuthType = auth_type - .try_into() + let auth = mollie::MollieAuthType::try_from(auth_type) .change_context(errors::ConnectorError::FailedToObtainAuthType)?; Ok(vec![( headers::AUTHORIZATION.to_string(), @@ -414,8 +413,8 @@ impl ConnectorIntegration, ) -> CustomResult { - Err(errors::ConnectorError::WebhooksNotImplemented).into_report() + Err(report!(errors::ConnectorError::WebhooksNotImplemented)) } fn get_webhook_event_type( @@ -620,7 +619,7 @@ impl api::IncomingWebhook for Mollie { &self, _request: &api::IncomingWebhookRequestDetails<'_>, ) -> CustomResult, errors::ConnectorError> { - Err(errors::ConnectorError::WebhooksNotImplemented).into_report() + Err(report!(errors::ConnectorError::WebhooksNotImplemented)) } } diff --git a/crates/router/src/connector/mollie/transformers.rs b/crates/router/src/connector/mollie/transformers.rs index be0c0475fd7..7acf81db295 100644 --- a/crates/router/src/connector/mollie/transformers.rs +++ b/crates/router/src/connector/mollie/transformers.rs @@ -2,7 +2,6 @@ use api_models::payments; use cards::CardNumber; use common_utils::pii::Email; use diesel_models::enums; -use error_stack::IntoReport; use masking::{ExposeInterface, Secret}; use serde::{Deserialize, Serialize}; use url::Url; @@ -198,10 +197,9 @@ impl TryFrom<&MollieRouterData<&types::PaymentsAuthorizeRouterData>> for MollieP api_models::payments::PaymentMethodData::BankDebit(ref directdebit_data) => { PaymentMethodData::try_from(directdebit_data) } - _ => Err(errors::ConnectorError::NotImplemented( - "Payment Method".to_string(), - )) - .into_report(), + _ => Err( + errors::ConnectorError::NotImplemented("Payment Method".to_string()).into(), + ), } } _ => Err(errors::ConnectorError::FlowNotSupported { @@ -210,8 +208,8 @@ impl TryFrom<&MollieRouterData<&types::PaymentsAuthorizeRouterData>> for MollieP item.router_data.request.capture_method.unwrap_or_default() ), connector: "Mollie".to_string(), - }) - .into_report(), + } + .into()), }?; Ok(Self { amount, @@ -341,10 +339,7 @@ fn get_payment_method_for_wallet( apple_pay_payment_token: Secret::new(applepay_wallet_data.payment_data.to_owned()), }))) } - _ => Err(errors::ConnectorError::NotImplemented( - "Payment Method".to_string(), - )) - .into_report(), + _ => Err(errors::ConnectorError::NotImplemented("Payment Method".to_string()).into()), } } diff --git a/crates/router/src/connector/multisafepay.rs b/crates/router/src/connector/multisafepay.rs index b039da42a0c..fa6bb5dad3f 100644 --- a/crates/router/src/connector/multisafepay.rs +++ b/crates/router/src/connector/multisafepay.rs @@ -3,7 +3,7 @@ pub mod transformers; use std::fmt::Debug; use common_utils::request::RequestContent; -use error_stack::{IntoReport, ResultExt}; +use error_stack::{report, ResultExt}; use masking::ExposeInterface; use transformers as multisafepay; @@ -63,8 +63,7 @@ impl ConnectorCommon for Multisafepay { &self, auth_type: &types::ConnectorAuthType, ) -> CustomResult)>, errors::ConnectorError> { - let auth: multisafepay::MultisafepayAuthType = auth_type - .try_into() + let auth = multisafepay::MultisafepayAuthType::try_from(auth_type) .change_context(errors::ConnectorError::FailedToObtainAuthType)?; Ok(vec![( headers::AUTHORIZATION.to_string(), @@ -339,12 +338,11 @@ impl ConnectorIntegration, ) -> CustomResult { - Err(errors::ConnectorError::WebhooksNotImplemented).into_report() + Err(report!(errors::ConnectorError::WebhooksNotImplemented)) } fn get_webhook_event_type( @@ -553,6 +549,6 @@ impl api::IncomingWebhook for Multisafepay { &self, _request: &api::IncomingWebhookRequestDetails<'_>, ) -> CustomResult, errors::ConnectorError> { - Err(errors::ConnectorError::WebhooksNotImplemented).into_report() + Err(report!(errors::ConnectorError::WebhooksNotImplemented)) } } diff --git a/crates/router/src/connector/nexinets.rs b/crates/router/src/connector/nexinets.rs index 85cc0949814..1370fcf11cd 100644 --- a/crates/router/src/connector/nexinets.rs +++ b/crates/router/src/connector/nexinets.rs @@ -3,7 +3,7 @@ pub mod transformers; use std::fmt::Debug; use common_utils::request::RequestContent; -use error_stack::{IntoReport, ResultExt}; +use error_stack::{report, ResultExt}; use transformers as nexinets; use crate::{ @@ -707,7 +707,7 @@ impl api::IncomingWebhook for Nexinets { &self, _request: &api::IncomingWebhookRequestDetails<'_>, ) -> CustomResult { - Err(errors::ConnectorError::WebhooksNotImplemented).into_report() + Err(report!(errors::ConnectorError::WebhooksNotImplemented)) } fn get_webhook_event_type( @@ -721,7 +721,7 @@ impl api::IncomingWebhook for Nexinets { &self, _request: &api::IncomingWebhookRequestDetails<'_>, ) -> CustomResult, errors::ConnectorError> { - Err(errors::ConnectorError::WebhooksNotImplemented).into_report() + Err(report!(errors::ConnectorError::WebhooksNotImplemented)) } } diff --git a/crates/router/src/connector/nexinets/transformers.rs b/crates/router/src/connector/nexinets/transformers.rs index dc871891145..703c24e56e9 100644 --- a/crates/router/src/connector/nexinets/transformers.rs +++ b/crates/router/src/connector/nexinets/transformers.rs @@ -2,7 +2,7 @@ use api_models::payments::PaymentMethodData; use base64::Engine; use cards::CardNumber; use common_utils::errors::CustomResult; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use masking::{ExposeInterface, PeekInterface, Secret}; use serde::{Deserialize, Serialize}; use url::Url; @@ -339,7 +339,6 @@ impl order_id: Some(item.response.order_id.clone()), psync_flow: item.response.transaction_type.clone(), }) - .into_report() .change_context(errors::ConnectorError::ResponseHandlingFailed)?; let redirection_data = item .response @@ -436,7 +435,6 @@ impl order_id: Some(item.response.order.order_id.clone()), psync_flow: item.response.transaction_type.clone(), }) - .into_report() .change_context(errors::ConnectorError::ResponseHandlingFailed)?; let resource_id = match item.response.transaction_type.clone() { NexinetsTransactionType::Debit | NexinetsTransactionType::Capture => { diff --git a/crates/router/src/connector/nmi.rs b/crates/router/src/connector/nmi.rs index 527403736aa..d34b894411f 100644 --- a/crates/router/src/connector/nmi.rs +++ b/crates/router/src/connector/nmi.rs @@ -4,7 +4,7 @@ use std::fmt::Debug; use common_utils::{crypto, ext_traits::ByteSliceExt, request::RequestContent}; use diesel_models::enums; -use error_stack::{IntoReport, ResultExt}; +use error_stack::{report, ResultExt}; use regex::Regex; use transformers as nmi; @@ -195,7 +195,6 @@ impl res: types::Response, ) -> CustomResult { let response: nmi::StandardResponse = serde_urlencoded::from_bytes(&res.response) - .into_report() .change_context(errors::ConnectorError::ResponseDeserializationFailed)?; event_builder.map(|i| i.set_response_body(&response)); router_env::logger::info!(connector_response=?response); @@ -283,7 +282,6 @@ impl res: types::Response, ) -> CustomResult { let response: nmi::NmiVaultResponse = serde_urlencoded::from_bytes(&res.response) - .into_report() .change_context(errors::ConnectorError::ResponseDeserializationFailed)?; event_builder.map(|i| i.set_response_body(&response)); router_env::logger::info!(connector_response=?response); @@ -365,7 +363,6 @@ impl ConnectorIntegration CustomResult { let response: nmi::StandardResponse = serde_urlencoded::from_bytes(&res.response) - .into_report() .change_context(errors::ConnectorError::ResponseDeserializationFailed)?; event_builder.map(|i| i.set_response_body(&response)); router_env::logger::info!(connector_response=?response); @@ -454,7 +451,6 @@ impl res: types::Response, ) -> CustomResult { let response: nmi::NmiCompleteResponse = serde_urlencoded::from_bytes(&res.response) - .into_report() .change_context(errors::ConnectorError::ResponseDeserializationFailed)?; event_builder.map(|i| i.set_response_body(&response)); router_env::logger::info!(connector_response=?response); @@ -605,7 +601,6 @@ impl ConnectorIntegration CustomResult { let response: nmi::StandardResponse = serde_urlencoded::from_bytes(&res.response) - .into_report() .change_context(errors::ConnectorError::ResponseDeserializationFailed)?; event_builder.map(|i| i.set_response_body(&response)); router_env::logger::info!(connector_response=?response); @@ -677,7 +672,6 @@ impl ConnectorIntegration CustomResult { let response: nmi::StandardResponse = serde_urlencoded::from_bytes(&res.response) - .into_report() .change_context(errors::ConnectorError::ResponseDeserializationFailed)?; event_builder.map(|i| i.set_response_body(&response)); router_env::logger::info!(connector_response=?response); @@ -755,7 +749,6 @@ impl ConnectorIntegration CustomResult, errors::ConnectorError> { let response: nmi::StandardResponse = serde_urlencoded::from_bytes(&res.response) - .into_report() .change_context(errors::ConnectorError::ResponseDeserializationFailed)?; event_builder.map(|i| i.set_response_body(&response)); router_env::logger::info!(connector_response=?response); @@ -865,19 +858,17 @@ impl api::IncomingWebhook for Nmi { let regex_pattern = r"t=(.*),s=(.*)"; if let Some(captures) = Regex::new(regex_pattern) - .into_report() .change_context(errors::ConnectorError::WebhookSignatureNotFound)? .captures(sig_header) { let signature = captures .get(1) - .ok_or(errors::ConnectorError::WebhookSignatureNotFound) - .into_report()? + .ok_or(errors::ConnectorError::WebhookSignatureNotFound)? .as_str(); return Ok(signature.as_bytes().to_vec()); } - Err(errors::ConnectorError::WebhookSignatureNotFound).into_report() + Err(report!(errors::ConnectorError::WebhookSignatureNotFound)) } fn get_webhook_source_verification_message( @@ -892,21 +883,19 @@ impl api::IncomingWebhook for Nmi { let regex_pattern = r"t=(.*),s=(.*)"; if let Some(captures) = Regex::new(regex_pattern) - .into_report() .change_context(errors::ConnectorError::WebhookSignatureNotFound)? .captures(sig_header) { let nonce = captures .get(0) - .ok_or(errors::ConnectorError::WebhookSignatureNotFound) - .into_report()? + .ok_or(errors::ConnectorError::WebhookSignatureNotFound)? .as_str(); let message = format!("{}.{}", nonce, String::from_utf8_lossy(request.body)); return Ok(message.into_bytes()); } - Err(errors::ConnectorError::WebhookSignatureNotFound).into_report() + Err(report!(errors::ConnectorError::WebhookSignatureNotFound)) } fn get_webhook_object_reference_id( @@ -942,7 +931,7 @@ impl api::IncomingWebhook for Nmi { nmi::NmiActionType::Refund => api_models::webhooks::ObjectReferenceId::RefundId( api_models::webhooks::RefundIdType::RefundId(reference_body.event_body.order_id), ), - _ => Err(errors::ConnectorError::WebhooksNotImplemented).into_report()?, + _ => Err(errors::ConnectorError::WebhooksNotImplemented)?, }; Ok(object_reference_id) @@ -999,10 +988,11 @@ impl services::ConnectorRedirectResponse for Nmi { })?; let redirect_res: nmi::NmiRedirectResponse = serde_json::from_value(payload_data) - .into_report() - .change_context(errors::ConnectorError::MissingConnectorRedirectionPayload { + .change_context( + errors::ConnectorError::MissingConnectorRedirectionPayload { field_name: "redirect_res", - })?; + }, + )?; match redirect_res { transformers::NmiRedirectResponse::NmiRedirectResponseData(_) => { diff --git a/crates/router/src/connector/nmi/transformers.rs b/crates/router/src/connector/nmi/transformers.rs index efde37d8715..2358e0f6cc0 100644 --- a/crates/router/src/connector/nmi/transformers.rs +++ b/crates/router/src/connector/nmi/transformers.rs @@ -6,7 +6,7 @@ use common_utils::{ ext_traits::XmlExt, pii::{self, Email}, }; -use error_stack::{IntoReport, Report, ResultExt}; +use error_stack::{Report, ResultExt}; use masking::{ExposeInterface, PeekInterface, Secret}; use serde::{Deserialize, Serialize}; @@ -149,8 +149,8 @@ fn get_card_details( )), _ => Err(errors::ConnectorError::NotImplemented( utils::get_unimplemented_payment_method_error_message("Nmi"), - )) - .into_report(), + ) + .into()), } } @@ -314,7 +314,6 @@ impl TryFrom<&NmiRouterData<&types::PaymentsCompleteAuthorizeRouterData>> for Nm .expose(); let three_ds_data: NmiRedirectResponseData = serde_json::from_value(payload_data) - .into_report() .change_context(errors::ConnectorError::MissingConnectorRedirectionPayload { field_name: "three_ds_data", })?; @@ -554,8 +553,8 @@ impl TryFrom<&api_models::payments::PaymentMethodData> for PaymentMethod { | api_models::payments::WalletData::SwishQr(_) => { Err(errors::ConnectorError::NotImplemented( utils::get_unimplemented_payment_method_error_message("nmi"), - )) - .into_report() + ) + .into()) } }, api::PaymentMethodData::CardRedirect(_) @@ -571,8 +570,8 @@ impl TryFrom<&api_models::payments::PaymentMethodData> for PaymentMethod { | api::PaymentMethodData::GiftCard(_) | api::PaymentMethodData::CardToken(_) => Err(errors::ConnectorError::NotImplemented( utils::get_unimplemented_payment_method_error_message("nmi"), - )) - .into_report(), + ) + .into()), } } } @@ -962,11 +961,9 @@ impl TryFrom> for SyncResponse { type Error = Error; fn try_from(bytes: Vec) -> Result { let query_response = String::from_utf8(bytes) - .into_report() .change_context(errors::ConnectorError::ResponseDeserializationFailed)?; query_response .parse_xml::() - .into_report() .change_context(errors::ConnectorError::ResponseDeserializationFailed) } } @@ -975,11 +972,9 @@ impl TryFrom> for NmiRefundSyncResponse { type Error = Error; fn try_from(bytes: Vec) -> Result { let query_response = String::from_utf8(bytes) - .into_report() .change_context(errors::ConnectorError::ResponseDeserializationFailed)?; query_response .parse_xml::() - .into_report() .change_context(errors::ConnectorError::ResponseDeserializationFailed) } } diff --git a/crates/router/src/connector/noon.rs b/crates/router/src/connector/noon.rs index d9e9417df8e..f247a5dae1f 100644 --- a/crates/router/src/connector/noon.rs +++ b/crates/router/src/connector/noon.rs @@ -5,7 +5,7 @@ use std::fmt::Debug; use base64::Engine; use common_utils::{crypto, ext_traits::ByteSliceExt, request::RequestContent}; use diesel_models::enums; -use error_stack::{IntoReport, Report, ResultExt}; +use error_stack::{Report, ResultExt}; use masking::PeekInterface; use router_env::logger; use transformers as noon; @@ -803,7 +803,6 @@ impl api::IncomingWebhook for Noon { let signature = webhook_body.signature; consts::BASE64_ENGINE .decode(signature) - .into_report() .change_context(errors::ConnectorError::WebhookSignatureNotFound) } diff --git a/crates/router/src/connector/noon/transformers.rs b/crates/router/src/connector/noon/transformers.rs index 92def17aeae..38202291b41 100644 --- a/crates/router/src/connector/noon/transformers.rs +++ b/crates/router/src/connector/noon/transformers.rs @@ -1,5 +1,5 @@ use common_utils::{ext_traits::Encode, pii}; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use masking::{ExposeInterface, PeekInterface, Secret}; use serde::{Deserialize, Serialize}; @@ -379,13 +379,13 @@ impl TryFrom<&types::PaymentsAuthorizeRouterData> for NoonPaymentsRequest { Err(errors::ConnectorError::MissingRequiredField { field_name: "setup_future_usage.mandate_data.mandate_type.multi_use.amount", - }) - .into_report() + } + .into()) } None => Err(errors::ConnectorError::MissingRequiredField { field_name: "setup_future_usage.mandate_data.mandate_type", - }) - .into_report(), + } + .into()), }?; Ok::>( diff --git a/crates/router/src/connector/nuvei.rs b/crates/router/src/connector/nuvei.rs index 0e9a9634402..0e3ae84581a 100644 --- a/crates/router/src/connector/nuvei.rs +++ b/crates/router/src/connector/nuvei.rs @@ -8,7 +8,7 @@ use ::common_utils::{ ext_traits::{BytesExt, ValueExt}, request::RequestContent, }; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use masking::ExposeInterface; use transformers as nuvei; @@ -290,7 +290,7 @@ impl ConnectorIntegration CustomResult, errors::ConnectorError> { let signature = utils::get_header_key_value("advanceResponseChecksum", request.headers)?; - hex::decode(signature) - .into_report() - .change_context(errors::ConnectorError::WebhookResponseEncodingFailed) + hex::decode(signature).change_context(errors::ConnectorError::WebhookResponseEncodingFailed) } fn get_webhook_source_verification_message( @@ -931,10 +929,8 @@ impl api::IncomingWebhook for Nuvei { connector_webhook_secrets: &api_models::webhooks::ConnectorWebhookSecrets, ) -> CustomResult, errors::ConnectorError> { let body = serde_urlencoded::from_str::(&request.query_params) - .into_report() .change_context(errors::ConnectorError::WebhookBodyDecodingFailed)?; let secret_str = std::str::from_utf8(&connector_webhook_secrets.secret) - .into_report() .change_context(errors::ConnectorError::WebhookBodyDecodingFailed)?; let status = format!("{:?}", body.status).to_uppercase(); let to_sign = format!( @@ -956,7 +952,6 @@ impl api::IncomingWebhook for Nuvei { ) -> CustomResult { let body = serde_urlencoded::from_str::(&request.query_params) - .into_report() .change_context(errors::ConnectorError::WebhookBodyDecodingFailed)?; Ok(api_models::webhooks::ObjectReferenceId::PaymentId( types::api::PaymentIdType::ConnectorTransactionId(body.ppp_transaction_id), @@ -969,7 +964,6 @@ impl api::IncomingWebhook for Nuvei { ) -> CustomResult { let body = serde_urlencoded::from_str::(&request.query_params) - .into_report() .change_context(errors::ConnectorError::WebhookBodyDecodingFailed)?; match body.status { nuvei::NuveiWebhookStatus::Approved => { @@ -989,7 +983,6 @@ impl api::IncomingWebhook for Nuvei { request: &api::IncomingWebhookRequestDetails<'_>, ) -> CustomResult, errors::ConnectorError> { let body = serde_urlencoded::from_str::(&request.query_params) - .into_report() .change_context(errors::ConnectorError::WebhookBodyDecodingFailed)?; let payment_response = nuvei::NuveiPaymentsResponse::from(body); diff --git a/crates/router/src/connector/nuvei/transformers.rs b/crates/router/src/connector/nuvei/transformers.rs index 77c08a4374f..6753dfe203f 100644 --- a/crates/router/src/connector/nuvei/transformers.rs +++ b/crates/router/src/connector/nuvei/transformers.rs @@ -7,7 +7,7 @@ use common_utils::{ pii::{Email, IpAddress}, }; use data_models::mandates::MandateDataType; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use masking::{ExposeInterface, PeekInterface, Secret}; use reqwest::Url; use serde::{Deserialize, Serialize}; @@ -1080,7 +1080,6 @@ impl TryFrom for NuveiPaymentsRequest { let client_request_id = request.client_request_id; let time_stamp = date_time::format_date(date_time::now(), date_time::DateFormat::YYYYMMDDHHmmss) - .into_report() .change_context(errors::ConnectorError::RequestEncodingFailed)?; let merchant_secret = connector_meta.merchant_secret; Ok(Self { @@ -1118,7 +1117,6 @@ impl TryFrom for NuveiPaymentFlowRequest { let client_request_id = request.client_request_id; let time_stamp = date_time::format_date(date_time::now(), date_time::DateFormat::YYYYMMDDHHmmss) - .into_report() .change_context(errors::ConnectorError::RequestEncodingFailed)?; let merchant_secret = connector_meta.merchant_secret; Ok(Self { @@ -1455,7 +1453,6 @@ where serde_json::to_value(NuveiMeta { session_token: token, }) - .into_report() .change_context(errors::ConnectorError::ResponseHandlingFailed)?, ) } else { diff --git a/crates/router/src/connector/opayo.rs b/crates/router/src/connector/opayo.rs index 53a314162bb..cd1ef67f662 100644 --- a/crates/router/src/connector/opayo.rs +++ b/crates/router/src/connector/opayo.rs @@ -4,7 +4,7 @@ use std::fmt::Debug; use common_utils::request::RequestContent; use diesel_models::enums; -use error_stack::{IntoReport, ResultExt}; +use error_stack::{report, ResultExt}; use masking::ExposeInterface; use transformers as opayo; @@ -559,20 +559,20 @@ impl api::IncomingWebhook for Opayo { &self, _request: &api::IncomingWebhookRequestDetails<'_>, ) -> CustomResult { - Err(errors::ConnectorError::WebhooksNotImplemented).into_report() + Err(report!(errors::ConnectorError::WebhooksNotImplemented)) } fn get_webhook_event_type( &self, _request: &api::IncomingWebhookRequestDetails<'_>, ) -> CustomResult { - Err(errors::ConnectorError::WebhooksNotImplemented).into_report() + Err(report!(errors::ConnectorError::WebhooksNotImplemented)) } fn get_webhook_resource_object( &self, _request: &api::IncomingWebhookRequestDetails<'_>, ) -> CustomResult, errors::ConnectorError> { - Err(errors::ConnectorError::WebhooksNotImplemented).into_report() + Err(report!(errors::ConnectorError::WebhooksNotImplemented)) } } diff --git a/crates/router/src/connector/opennode.rs b/crates/router/src/connector/opennode.rs index 1bd7461b668..5346fc086d7 100644 --- a/crates/router/src/connector/opennode.rs +++ b/crates/router/src/connector/opennode.rs @@ -3,7 +3,7 @@ pub mod transformers; use std::fmt::Debug; use common_utils::{crypto, request::RequestContent}; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use transformers as opennode; use self::opennode::OpennodeWebhookDetails; @@ -389,11 +389,9 @@ impl api::IncomingWebhook for Opennode { _connector_webhook_secrets: &api_models::webhooks::ConnectorWebhookSecrets, ) -> CustomResult, errors::ConnectorError> { let notif = serde_urlencoded::from_bytes::(request.body) - .into_report() .change_context(errors::ConnectorError::WebhookBodyDecodingFailed)?; let base64_signature = notif.hashed_order; hex::decode(base64_signature) - .into_report() .change_context(errors::ConnectorError::WebhookSourceVerificationFailed) } @@ -404,7 +402,6 @@ impl api::IncomingWebhook for Opennode { _connector_webhook_secrets: &api_models::webhooks::ConnectorWebhookSecrets, ) -> CustomResult, errors::ConnectorError> { let message = std::str::from_utf8(request.body) - .into_report() .change_context(errors::ConnectorError::ParsingFailed)?; Ok(message.to_string().into_bytes()) } @@ -414,7 +411,6 @@ impl api::IncomingWebhook for Opennode { request: &api::IncomingWebhookRequestDetails<'_>, ) -> CustomResult { let notif = serde_urlencoded::from_bytes::(request.body) - .into_report() .change_context(errors::ConnectorError::WebhookBodyDecodingFailed)?; Ok(api_models::webhooks::ObjectReferenceId::PaymentId( api_models::payments::PaymentIdType::ConnectorTransactionId(notif.id), @@ -426,7 +422,6 @@ impl api::IncomingWebhook for Opennode { request: &api::IncomingWebhookRequestDetails<'_>, ) -> CustomResult { let notif = serde_urlencoded::from_bytes::(request.body) - .into_report() .change_context(errors::ConnectorError::WebhookBodyDecodingFailed)?; match notif.status { @@ -449,7 +444,6 @@ impl api::IncomingWebhook for Opennode { request: &api::IncomingWebhookRequestDetails<'_>, ) -> CustomResult, errors::ConnectorError> { let notif = serde_urlencoded::from_bytes::(request.body) - .into_report() .change_context(errors::ConnectorError::WebhookBodyDecodingFailed)?; Ok(Box::new(notif.status)) diff --git a/crates/router/src/connector/payeezy.rs b/crates/router/src/connector/payeezy.rs index d24a42085a4..5783cf1bc14 100644 --- a/crates/router/src/connector/payeezy.rs +++ b/crates/router/src/connector/payeezy.rs @@ -5,7 +5,7 @@ use std::fmt::Debug; use base64::Engine; use common_utils::request::RequestContent; use diesel_models::enums; -use error_stack::{IntoReport, ResultExt}; +use error_stack::{report, ResultExt}; use masking::ExposeInterface; use rand::distributions::DistString; use ring::hmac; @@ -572,7 +572,7 @@ impl ConnectorIntegration, ) -> CustomResult { - Err(errors::ConnectorError::WebhooksNotImplemented).into_report() + Err(report!(errors::ConnectorError::WebhooksNotImplemented)) } fn get_webhook_event_type( @@ -611,6 +611,6 @@ impl api::IncomingWebhook for Payeezy { &self, _request: &api::IncomingWebhookRequestDetails<'_>, ) -> CustomResult, errors::ConnectorError> { - Err(errors::ConnectorError::WebhooksNotImplemented).into_report() + Err(report!(errors::ConnectorError::WebhooksNotImplemented)) } } diff --git a/crates/router/src/connector/payme.rs b/crates/router/src/connector/payme.rs index 5873609e372..042b506b306 100644 --- a/crates/router/src/connector/payme.rs +++ b/crates/router/src/connector/payme.rs @@ -5,7 +5,7 @@ use std::fmt::Debug; use api_models::enums::AuthenticationType; use common_utils::{crypto, request::RequestContent}; use diesel_models::enums; -use error_stack::{IntoReport, Report, ResultExt}; +use error_stack::{Report, ResultExt}; use masking::ExposeInterface; use transformers as payme; @@ -1086,7 +1086,6 @@ impl api::IncomingWebhook for Payme { ) -> CustomResult, errors::ConnectorError> { let resource = serde_urlencoded::from_bytes::(request.body) - .into_report() .change_context(errors::ConnectorError::WebhookBodyDecodingFailed)?; Ok(resource.payme_signature.expose().into_bytes()) } @@ -1099,7 +1098,6 @@ impl api::IncomingWebhook for Payme { ) -> CustomResult, errors::ConnectorError> { let resource = serde_urlencoded::from_bytes::(request.body) - .into_report() .change_context(errors::ConnectorError::WebhookBodyDecodingFailed)?; Ok(format!( "{}{}{}", @@ -1145,7 +1143,6 @@ impl api::IncomingWebhook for Payme { let mut message_to_verify = connector_webhook_secrets .additional_secret .ok_or(errors::ConnectorError::WebhookSourceVerificationFailed) - .into_report() .attach_printable("Failed to get additional secrets")? .expose() .as_bytes() @@ -1154,7 +1151,6 @@ impl api::IncomingWebhook for Payme { message_to_verify.append(&mut message); let signature_to_verify = hex::decode(signature) - .into_report() .change_context(errors::ConnectorError::WebhookResponseEncodingFailed)?; algorithm .verify_signature( @@ -1171,7 +1167,6 @@ impl api::IncomingWebhook for Payme { ) -> CustomResult { let resource = serde_urlencoded::from_bytes::(request.body) - .into_report() .change_context(errors::ConnectorError::WebhookBodyDecodingFailed)?; let id = match resource.notify_type { transformers::NotifyType::SaleComplete @@ -1200,7 +1195,6 @@ impl api::IncomingWebhook for Payme { ) -> CustomResult { let resource = serde_urlencoded::from_bytes::(request.body) - .into_report() .change_context(errors::ConnectorError::WebhookBodyDecodingFailed)?; Ok(api::IncomingWebhookEvent::from(resource.notify_type)) } @@ -1211,7 +1205,6 @@ impl api::IncomingWebhook for Payme { ) -> CustomResult, errors::ConnectorError> { let resource = serde_urlencoded::from_bytes::(request.body) - .into_report() .change_context(errors::ConnectorError::WebhookBodyDecodingFailed)?; match resource.notify_type { @@ -1234,7 +1227,6 @@ impl api::IncomingWebhook for Payme { ) -> CustomResult { let webhook_object = serde_urlencoded::from_bytes::(request.body) - .into_report() .change_context(errors::ConnectorError::WebhookBodyDecodingFailed)?; Ok(api::disputes::DisputePayload { diff --git a/crates/router/src/connector/payme/transformers.rs b/crates/router/src/connector/payme/transformers.rs index 4db0a0bd07b..b577ae9f20a 100644 --- a/crates/router/src/connector/payme/transformers.rs +++ b/crates/router/src/connector/payme/transformers.rs @@ -5,7 +5,7 @@ use api_models::{ payments::PaymentMethodData, }; use common_utils::pii; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use masking::{ExposeInterface, Secret}; use serde::{Deserialize, Serialize}; use url::Url; @@ -696,7 +696,6 @@ impl TryFrom<&types::PaymentsCompleteAuthorizeRouterData> for Pay3dsRequest { let payload_data = item.request.get_redirect_response_payload()?.expose(); let jwt_data: PaymeRedirectResponseData = serde_json::from_value(payload_data) - .into_report() .change_context(errors::ConnectorError::MissingConnectorRedirectionPayload { field_name: "meta_data_jwt", })?; diff --git a/crates/router/src/connector/paypal.rs b/crates/router/src/connector/paypal.rs index 1aa1252bdd1..69bf3f72493 100644 --- a/crates/router/src/connector/paypal.rs +++ b/crates/router/src/connector/paypal.rs @@ -4,7 +4,7 @@ use std::fmt::{Debug, Write}; use base64::Engine; use common_utils::{ext_traits::ByteSliceExt, request::RequestContent}; use diesel_models::enums; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use masking::{ExposeInterface, PeekInterface, Secret}; use transformers as paypal; @@ -245,7 +245,6 @@ impl ConnectorCommon for Paypal { .try_fold(String::new(), |mut acc, error| { if let Some(description) = &error.description { write!(acc, "description - {} ;", description) - .into_report() .change_context( errors::ConnectorError::ResponseDeserializationFailed, ) diff --git a/crates/router/src/connector/paypal/transformers.rs b/crates/router/src/connector/paypal/transformers.rs index d2d3989a692..439184cafca 100644 --- a/crates/router/src/connector/paypal/transformers.rs +++ b/crates/router/src/connector/paypal/transformers.rs @@ -1,7 +1,7 @@ use api_models::{enums, payments::BankRedirectData}; use base64::Engine; use common_utils::errors::CustomResult; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use masking::{ExposeInterface, Secret}; use serde::{Deserialize, Serialize}; use time::PrimitiveDateTime; @@ -2133,7 +2133,6 @@ impl TryFrom<&types::VerifyWebhookSourceRequestData> for PaypalSourceVerificatio type Error = error_stack::Report; fn try_from(req: &types::VerifyWebhookSourceRequestData) -> Result { let req_body = serde_json::from_slice(&req.webhook_body) - .into_report() .change_context(errors::ConnectorError::WebhookBodyDecodingFailed)?; Ok(Self { transmission_id: get_headers( @@ -2152,7 +2151,6 @@ impl TryFrom<&types::VerifyWebhookSourceRequestData> for PaypalSourceVerificatio )?, auth_algo: get_headers(&req.webhook_headers, webhook_headers::PAYPAL_AUTH_ALGO)?, webhook_id: String::from_utf8(req.merchant_secret.secret.to_vec()) - .into_report() .change_context(errors::ConnectorError::WebhookVerificationSecretNotFound) .attach_printable("Could not convert secret to UTF-8")?, webhook_event: req_body, @@ -2168,7 +2166,6 @@ fn get_headers( .get(key) .map(|value| value.to_str()) .ok_or(errors::ConnectorError::MissingRequiredField { field_name: key })? - .into_report() .change_context(errors::ConnectorError::InvalidDataFormat { field_name: key })? .to_owned(); Ok(header_value) diff --git a/crates/router/src/connector/payu.rs b/crates/router/src/connector/payu.rs index 3ff0e709367..4ff317d1f71 100644 --- a/crates/router/src/connector/payu.rs +++ b/crates/router/src/connector/payu.rs @@ -4,7 +4,7 @@ use std::fmt::Debug; use common_utils::request::RequestContent; use diesel_models::enums; -use error_stack::{IntoReport, ResultExt}; +use error_stack::{report, ResultExt}; use masking::PeekInterface; use transformers as payu; @@ -75,8 +75,7 @@ impl ConnectorCommon for Payu { &self, auth_type: &types::ConnectorAuthType, ) -> CustomResult)>, errors::ConnectorError> { - let auth: payu::PayuAuthType = auth_type - .try_into() + let auth = payu::PayuAuthType::try_from(auth_type) .change_context(errors::ConnectorError::FailedToObtainAuthType)?; Ok(vec![( headers::AUTHORIZATION.to_string(), @@ -312,12 +311,11 @@ impl ConnectorIntegration, ) -> CustomResult { - Err(errors::ConnectorError::WebhooksNotImplemented).into_report() + Err(report!(errors::ConnectorError::WebhooksNotImplemented)) } fn get_webhook_event_type( @@ -796,6 +789,6 @@ impl api::IncomingWebhook for Payu { &self, _request: &api::IncomingWebhookRequestDetails<'_>, ) -> CustomResult, errors::ConnectorError> { - Err(errors::ConnectorError::WebhooksNotImplemented).into_report() + Err(report!(errors::ConnectorError::WebhooksNotImplemented)) } } diff --git a/crates/router/src/connector/payu/transformers.rs b/crates/router/src/connector/payu/transformers.rs index e8699a1a0ed..9484749ff22 100644 --- a/crates/router/src/connector/payu/transformers.rs +++ b/crates/router/src/connector/payu/transformers.rs @@ -1,6 +1,6 @@ use base64::Engine; use common_utils::pii::{Email, IpAddress}; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use serde::{Deserialize, Serialize}; use crate::{ @@ -489,7 +489,6 @@ impl order .total_amount .parse::() - .into_report() .change_context(errors::ConnectorError::ResponseDeserializationFailed)?, ), ..item.data diff --git a/crates/router/src/connector/placetopay.rs b/crates/router/src/connector/placetopay.rs index c28fed1fede..86a37bb0e21 100644 --- a/crates/router/src/connector/placetopay.rs +++ b/crates/router/src/connector/placetopay.rs @@ -3,7 +3,7 @@ pub mod transformers; use std::fmt::Debug; use common_utils::request::RequestContent; -use error_stack::{IntoReport, ResultExt}; +use error_stack::{report, ResultExt}; use transformers as placetopay; use crate::{ @@ -662,20 +662,20 @@ impl api::IncomingWebhook for Placetopay { &self, _request: &api::IncomingWebhookRequestDetails<'_>, ) -> CustomResult { - Err(errors::ConnectorError::WebhooksNotImplemented).into_report() + Err(report!(errors::ConnectorError::WebhooksNotImplemented)) } fn get_webhook_event_type( &self, _request: &api::IncomingWebhookRequestDetails<'_>, ) -> CustomResult { - Err(errors::ConnectorError::WebhooksNotImplemented).into_report() + Err(report!(errors::ConnectorError::WebhooksNotImplemented)) } fn get_webhook_resource_object( &self, _request: &api::IncomingWebhookRequestDetails<'_>, ) -> CustomResult, errors::ConnectorError> { - Err(errors::ConnectorError::WebhooksNotImplemented).into_report() + Err(report!(errors::ConnectorError::WebhooksNotImplemented)) } } diff --git a/crates/router/src/connector/placetopay/transformers.rs b/crates/router/src/connector/placetopay/transformers.rs index 1c3b46fdb60..152e315de18 100644 --- a/crates/router/src/connector/placetopay/transformers.rs +++ b/crates/router/src/connector/placetopay/transformers.rs @@ -1,7 +1,7 @@ use api_models::payments; use common_utils::date_time; use diesel_models::enums; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use masking::{PeekInterface, Secret}; use ring::digest; use serde::{Deserialize, Serialize}; @@ -171,7 +171,7 @@ impl TryFrom<&types::ConnectorAuthType> for PlacetopayAuth { fn try_from(auth_type: &types::ConnectorAuthType) -> Result { let placetopay_auth = PlacetopayAuthType::try_from(auth_type)?; let nonce_bytes = utils::generate_random_bytes(16); - let now = error_stack::IntoReport::into_report(date_time::date_as_yyyymmddthhmmssmmmz()) + let now = date_time::date_as_yyyymmddthhmmssmmmz() .change_context(errors::ConnectorError::RequestEncodingFailed)?; let seed = format!("{}+00:00", now.split_at(now.len() - 5).0); let mut context = digest::Context::new(&digest::SHA256); @@ -312,7 +312,6 @@ impl TryFrom<&types::RefundsRouterData> for PlacetopayRefundRequest { .request .connector_transaction_id .parse::() - .into_report() .change_context(errors::ConnectorError::RequestEncodingFailed)?; let action = PlacetopayNextAction::Reverse; let authorization = match item.request.connector_metadata.clone() { @@ -417,7 +416,6 @@ impl TryFrom<&types::RefundsRouterData> for PlacetopayRsyncRequest { .request .connector_transaction_id .parse::() - .into_report() .change_context(errors::ConnectorError::RequestEncodingFailed)?; Ok(Self { auth, @@ -479,7 +477,6 @@ impl TryFrom<&types::PaymentsSyncRouterData> for PlacetopayPsyncRequest { .request .get_connector_transaction_id()? .parse::() - .into_report() .change_context(errors::ConnectorError::RequestEncodingFailed)?; Ok(Self { auth, @@ -515,7 +512,6 @@ impl TryFrom<&types::PaymentsCaptureRouterData> for PlacetopayNextActionRequest .request .connector_transaction_id .parse::() - .into_report() .change_context(errors::ConnectorError::RequestEncodingFailed)?; let action = PlacetopayNextAction::Checkout; Ok(Self { @@ -535,7 +531,6 @@ impl TryFrom<&types::PaymentsCancelRouterData> for PlacetopayNextActionRequest { .request .connector_transaction_id .parse::() - .into_report() .change_context(errors::ConnectorError::RequestEncodingFailed)?; let action = PlacetopayNextAction::Void; Ok(Self { diff --git a/crates/router/src/connector/powertranz.rs b/crates/router/src/connector/powertranz.rs index a26886384c0..9e514a43553 100644 --- a/crates/router/src/connector/powertranz.rs +++ b/crates/router/src/connector/powertranz.rs @@ -5,7 +5,7 @@ use std::fmt::Debug; use api_models::enums::AuthenticationType; use common_utils::{ext_traits::ValueExt, request::RequestContent}; use diesel_models::enums; -use error_stack::{IntoReport, ResultExt}; +use error_stack::{report, ResultExt}; use masking::ExposeInterface; use transformers as powertranz; @@ -622,20 +622,20 @@ impl api::IncomingWebhook for Powertranz { &self, _request: &api::IncomingWebhookRequestDetails<'_>, ) -> CustomResult { - Err(errors::ConnectorError::WebhooksNotImplemented).into_report() + Err(report!(errors::ConnectorError::WebhooksNotImplemented)) } fn get_webhook_event_type( &self, _request: &api::IncomingWebhookRequestDetails<'_>, ) -> CustomResult { - Err(errors::ConnectorError::WebhooksNotImplemented).into_report() + Err(report!(errors::ConnectorError::WebhooksNotImplemented)) } fn get_webhook_resource_object( &self, _request: &api::IncomingWebhookRequestDetails<'_>, ) -> CustomResult, errors::ConnectorError> { - Err(errors::ConnectorError::WebhooksNotImplemented).into_report() + Err(report!(errors::ConnectorError::WebhooksNotImplemented)) } } diff --git a/crates/router/src/connector/powertranz/transformers.rs b/crates/router/src/connector/powertranz/transformers.rs index 0af5dde6d00..26a8e4fc69e 100644 --- a/crates/router/src/connector/powertranz/transformers.rs +++ b/crates/router/src/connector/powertranz/transformers.rs @@ -1,7 +1,6 @@ use api_models::payments::Card; use common_utils::pii::{Email, IpAddress}; use diesel_models::enums::RefundStatus; -use error_stack::IntoReport; use masking::{ExposeInterface, Secret}; use serde::{Deserialize, Serialize}; use uuid::Uuid; @@ -117,8 +116,8 @@ impl TryFrom<&types::PaymentsAuthorizeRouterData> for PowertranzPaymentsRequest | api::PaymentMethodData::CardToken(_) => Err(errors::ConnectorError::NotSupported { message: utils::SELECTED_PAYMENT_METHOD.to_string(), connector: "powertranz", - }) - .into_report(), + } + .into()), }?; // let billing_address = get_address_details(&item.address.billing, &item.request.email); // let shipping_address = get_address_details(&item.address.shipping, &item.request.email); diff --git a/crates/router/src/connector/prophetpay.rs b/crates/router/src/connector/prophetpay.rs index 04b3e7b6d65..ef49e716d9a 100644 --- a/crates/router/src/connector/prophetpay.rs +++ b/crates/router/src/connector/prophetpay.rs @@ -4,7 +4,7 @@ use std::fmt::Debug; use base64::Engine; use common_utils::request::RequestContent; -use error_stack::{IntoReport, ResultExt}; +use error_stack::{report, ResultExt}; use masking::PeekInterface; use transformers as prophetpay; @@ -710,20 +710,20 @@ impl api::IncomingWebhook for Prophetpay { &self, _request: &api::IncomingWebhookRequestDetails<'_>, ) -> CustomResult { - Err(errors::ConnectorError::WebhooksNotImplemented).into_report() + Err(report!(errors::ConnectorError::WebhooksNotImplemented)) } fn get_webhook_event_type( &self, _request: &api::IncomingWebhookRequestDetails<'_>, ) -> CustomResult { - Err(errors::ConnectorError::WebhooksNotImplemented).into_report() + Err(report!(errors::ConnectorError::WebhooksNotImplemented)) } fn get_webhook_resource_object( &self, _request: &api::IncomingWebhookRequestDetails<'_>, ) -> CustomResult, errors::ConnectorError> { - Err(errors::ConnectorError::WebhooksNotImplemented).into_report() + Err(report!(errors::ConnectorError::WebhooksNotImplemented)) } } diff --git a/crates/router/src/connector/prophetpay/transformers.rs b/crates/router/src/connector/prophetpay/transformers.rs index 563438203d8..06d23af33af 100644 --- a/crates/router/src/connector/prophetpay/transformers.rs +++ b/crates/router/src/connector/prophetpay/transformers.rs @@ -1,7 +1,7 @@ use std::collections::HashMap; use common_utils::{consts, errors::CustomResult}; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use masking::{ExposeInterface, PeekInterface, Secret}; use serde::{Deserialize, Serialize}; use url::Url; @@ -201,7 +201,6 @@ impl ); let redirect_url = Url::parse(url_data.as_str()) - .into_report() .change_context(errors::ConnectorError::ResponseDeserializationFailed)?; let redirection_data = get_redirect_url_form( @@ -304,10 +303,9 @@ fn get_card_token( .to_string(), ); } - Ok(queries) + Ok::<_, errors::ConnectorError>(queries) }) - .transpose() - .into_report()? + .transpose()? .ok_or(errors::ConnectorError::ResponseDeserializationFailed)?; for (key, val) in queries_params { diff --git a/crates/router/src/connector/rapyd.rs b/crates/router/src/connector/rapyd.rs index fd6de253047..c5f92c20f5c 100644 --- a/crates/router/src/connector/rapyd.rs +++ b/crates/router/src/connector/rapyd.rs @@ -8,7 +8,7 @@ use common_utils::{ request::RequestContent, }; use diesel_models::enums; -use error_stack::{IntoReport, Report, ResultExt}; +use error_stack::{Report, ResultExt}; use masking::{ExposeInterface, PeekInterface}; use rand::distributions::{Alphanumeric, DistString}; use ring::hmac; @@ -260,12 +260,11 @@ impl .change_context(errors::ConnectorError::ResponseDeserializationFailed)?; event_builder.map(|i| i.set_response_body(&response)); router_env::logger::info!(connector_response=?response); - types::ResponseRouterData { + types::RouterData::try_from(types::ResponseRouterData { response, data: data.clone(), http_code: res.status_code, - } - .try_into() + }) .change_context(errors::ConnectorError::ResponseHandlingFailed) } @@ -383,12 +382,11 @@ impl .change_context(errors::ConnectorError::ResponseDeserializationFailed)?; event_builder.map(|i| i.set_response_body(&response)); router_env::logger::info!(connector_response=?response); - types::ResponseRouterData { + types::RouterData::try_from(types::ResponseRouterData { response, data: data.clone(), http_code: res.status_code, - } - .try_into() + }) .change_context(errors::ConnectorError::ResponseHandlingFailed) } @@ -491,12 +489,11 @@ impl .change_context(errors::ConnectorError::ResponseDeserializationFailed)?; event_builder.map(|i| i.set_response_body(&response)); router_env::logger::info!(connector_response=?response); - types::ResponseRouterData { + types::RouterData::try_from(types::ResponseRouterData { response, data: data.clone(), http_code: res.status_code, - } - .try_into() + }) .change_context(errors::ConnectorError::ResponseHandlingFailed) } } @@ -725,12 +722,11 @@ impl services::ConnectorIntegration .as_ref() .filter(|redirect_str| !redirect_str.is_empty()) .map(|url| { - Url::parse(url).into_report().change_context( + Url::parse(url).change_context( errors::ConnectorError::FailedToObtainIntegrationUrl, ) }) diff --git a/crates/router/src/connector/riskified.rs b/crates/router/src/connector/riskified.rs index 298f8fb1564..b28fb5b27ef 100644 --- a/crates/router/src/connector/riskified.rs +++ b/crates/router/src/connector/riskified.rs @@ -3,7 +3,7 @@ use std::fmt::Debug; #[cfg(feature = "frm")] use common_utils::request::RequestContent; -use error_stack::{IntoReport, ResultExt}; +use error_stack::{report, ResultExt}; use masking::{ExposeInterface, PeekInterface}; use ring::hmac; use transformers as riskified; @@ -551,20 +551,20 @@ impl api::IncomingWebhook for Riskified { &self, _request: &api::IncomingWebhookRequestDetails<'_>, ) -> CustomResult { - Err(errors::ConnectorError::WebhooksNotImplemented).into_report() + Err(report!(errors::ConnectorError::WebhooksNotImplemented)) } fn get_webhook_event_type( &self, _request: &api::IncomingWebhookRequestDetails<'_>, ) -> CustomResult { - Err(errors::ConnectorError::WebhooksNotImplemented).into_report() + Err(report!(errors::ConnectorError::WebhooksNotImplemented)) } fn get_webhook_resource_object( &self, _request: &api::IncomingWebhookRequestDetails<'_>, ) -> CustomResult, errors::ConnectorError> { - Err(errors::ConnectorError::WebhooksNotImplemented).into_report() + Err(report!(errors::ConnectorError::WebhooksNotImplemented)) } } diff --git a/crates/router/src/connector/shift4.rs b/crates/router/src/connector/shift4.rs index 0128aa1c2fa..e11a79cb027 100644 --- a/crates/router/src/connector/shift4.rs +++ b/crates/router/src/connector/shift4.rs @@ -4,7 +4,7 @@ use std::fmt::Debug; use common_utils::{ext_traits::ByteSliceExt, request::RequestContent}; use diesel_models::enums; -use error_stack::{IntoReport, ResultExt}; +use error_stack::{report, ResultExt}; use transformers as shift4; use super::utils::{self as connector_utils, RefundsRequestData}; @@ -74,8 +74,7 @@ impl ConnectorCommon for Shift4 { &self, auth_type: &types::ConnectorAuthType, ) -> CustomResult)>, errors::ConnectorError> { - let auth: shift4::Shift4AuthType = auth_type - .try_into() + let auth = shift4::Shift4AuthType::try_from(auth_type) .change_context(errors::ConnectorError::FailedToObtainAuthType)?; Ok(vec![( headers::AUTHORIZATION.to_string(), @@ -432,12 +431,11 @@ impl ConnectorIntegration serde_json::to_value(Shift4CardToken { id: item.response.token.id, }) - .into_report() .change_context(errors::ConnectorError::ResponseDeserializationFailed)?, ), network_txn_id: None, diff --git a/crates/router/src/connector/signifyd.rs b/crates/router/src/connector/signifyd.rs index 7d19df12221..6e63d5487e5 100644 --- a/crates/router/src/connector/signifyd.rs +++ b/crates/router/src/connector/signifyd.rs @@ -3,7 +3,7 @@ use std::fmt::Debug; #[cfg(feature = "frm")] use common_utils::request::RequestContent; -use error_stack::{IntoReport, ResultExt}; +use error_stack::{report, ResultExt}; use masking::PeekInterface; use transformers as signifyd; @@ -647,20 +647,20 @@ impl api::IncomingWebhook for Signifyd { &self, _request: &api::IncomingWebhookRequestDetails<'_>, ) -> CustomResult { - Err(errors::ConnectorError::WebhooksNotImplemented).into_report() + Err(report!(errors::ConnectorError::WebhooksNotImplemented)) } fn get_webhook_event_type( &self, _request: &api::IncomingWebhookRequestDetails<'_>, ) -> CustomResult { - Err(errors::ConnectorError::WebhooksNotImplemented).into_report() + Err(report!(errors::ConnectorError::WebhooksNotImplemented)) } fn get_webhook_resource_object( &self, _request: &api::IncomingWebhookRequestDetails<'_>, ) -> CustomResult, errors::ConnectorError> { - Err(errors::ConnectorError::WebhooksNotImplemented).into_report() + Err(report!(errors::ConnectorError::WebhooksNotImplemented)) } } diff --git a/crates/router/src/connector/square.rs b/crates/router/src/connector/square.rs index 8bfc9582d0c..915a9a9ca11 100644 --- a/crates/router/src/connector/square.rs +++ b/crates/router/src/connector/square.rs @@ -5,7 +5,7 @@ use std::fmt::Debug; use api_models::enums; use base64::Engine; use common_utils::{ext_traits::ByteSliceExt, request::RequestContent}; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use masking::PeekInterface; use transformers as square; @@ -898,7 +898,6 @@ impl api::IncomingWebhook for Square { super_utils::get_header_key_value("x-square-hmacsha256-signature", request.headers)?; let signature = consts::BASE64_ENGINE .decode(encoded_signature) - .into_report() .change_context(errors::ConnectorError::WebhookSignatureNotFound)?; Ok(signature) } @@ -915,7 +914,6 @@ impl api::IncomingWebhook for Square { .ok_or(errors::ConnectorError::WebhookSourceVerificationFailed)?; let authority = header_value .to_str() - .into_report() .change_context(errors::ConnectorError::WebhookSourceVerificationFailed)?; Ok(format!( diff --git a/crates/router/src/connector/square/transformers.rs b/crates/router/src/connector/square/transformers.rs index 66a0282f923..064e8457403 100644 --- a/crates/router/src/connector/square/transformers.rs +++ b/crates/router/src/connector/square/transformers.rs @@ -1,5 +1,5 @@ use api_models::payments::{BankDebitData, PayLaterData, WalletData}; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use masking::{ExposeInterface, PeekInterface, Secret}; use serde::{Deserialize, Serialize}; @@ -43,7 +43,6 @@ impl TryFrom<(&types::TokenizationRouterData, api_models::payments::Card)> for S .get_expiry_year_4_digit() .peek() .parse::() - .into_report() .change_context(errors::ConnectorError::DateFormattingFailed)?, ); let exp_month = Secret::new( @@ -51,7 +50,6 @@ impl TryFrom<(&types::TokenizationRouterData, api_models::payments::Card)> for S .card_exp_month .peek() .parse::() - .into_report() .change_context(errors::ConnectorError::DateFormattingFailed)?, ); //The below error will never happen because if session-id is not generated it would give error in execute_pretasks itself. diff --git a/crates/router/src/connector/stax.rs b/crates/router/src/connector/stax.rs index 73bcb0b8c61..c923ca0577d 100644 --- a/crates/router/src/connector/stax.rs +++ b/crates/router/src/connector/stax.rs @@ -4,7 +4,7 @@ use std::fmt::Debug; use common_utils::{ext_traits::ByteSliceExt, request::RequestContent}; use diesel_models::enums; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use masking::PeekInterface; use transformers as stax; @@ -107,7 +107,6 @@ impl ConnectorCommon for Stax { message: consts::NO_ERROR_MESSAGE.to_string(), reason: Some( std::str::from_utf8(&res.response) - .into_report() .change_context(errors::ConnectorError::ResponseDeserializationFailed)? .to_owned(), ), @@ -927,7 +926,6 @@ impl api::IncomingWebhook for Stax { request: &api::IncomingWebhookRequestDetails<'_>, ) -> CustomResult, errors::ConnectorError> { let reference_object: serde_json::Value = serde_json::from_slice(request.body) - .into_report() .change_context(errors::ConnectorError::WebhookResourceObjectNotFound)?; Ok(Box::new(reference_object)) } diff --git a/crates/router/src/connector/stax/transformers.rs b/crates/router/src/connector/stax/transformers.rs index d28b5c1fa46..1d7cc63a937 100644 --- a/crates/router/src/connector/stax/transformers.rs +++ b/crates/router/src/connector/stax/transformers.rs @@ -1,5 +1,5 @@ use common_utils::pii::Email; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use masking::{ExposeInterface, Secret}; use serde::{Deserialize, Serialize}; @@ -157,8 +157,8 @@ impl TryFrom<&types::ConnectorCustomerRouterData> for StaxCustomerRequest { if item.request.email.is_none() && item.request.name.is_none() { Err(errors::ConnectorError::MissingRequiredField { field_name: "email or name", - }) - .into_report() + } + .into()) } else { Ok(Self { email: item.request.email.to_owned(), diff --git a/crates/router/src/connector/stripe.rs b/crates/router/src/connector/stripe.rs index bf942ea1b3f..a3cf0d5c837 100644 --- a/crates/router/src/connector/stripe.rs +++ b/crates/router/src/connector/stripe.rs @@ -4,7 +4,7 @@ use std::{collections::HashMap, fmt::Debug, ops::Deref}; use common_utils::request::RequestContent; use diesel_models::enums; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use masking::PeekInterface; use router_env::{instrument, tracing}; use stripe::auth_headers; @@ -53,8 +53,7 @@ impl ConnectorCommon for Stripe { &self, auth_type: &types::ConnectorAuthType, ) -> CustomResult)>, errors::ConnectorError> { - let auth: stripe::StripeAuthType = auth_type - .try_into() + let auth = stripe::StripeAuthType::try_from(auth_type) .change_context(errors::ConnectorError::FailedToObtainAuthType)?; Ok(vec![ ( @@ -1917,10 +1916,8 @@ fn get_signature_elements_from_header( .to_str() .map(String::from) .map_err(|_| errors::ConnectorError::WebhookSignatureNotFound) - .into_report() }) - .ok_or(errors::ConnectorError::WebhookSignatureNotFound) - .into_report()??; + .ok_or(errors::ConnectorError::WebhookSignatureNotFound)??; let props = security_header.split(',').collect::>(); let mut security_header_kvs: HashMap> = HashMap::with_capacity(props.len()); @@ -1928,8 +1925,7 @@ fn get_signature_elements_from_header( for prop_str in &props { let (prop_key, prop_value) = prop_str .split_once('=') - .ok_or(errors::ConnectorError::WebhookSourceVerificationFailed) - .into_report()?; + .ok_or(errors::ConnectorError::WebhookSourceVerificationFailed)?; security_header_kvs.insert(prop_key.to_string(), prop_value.bytes().collect()); } @@ -1955,12 +1951,9 @@ impl api::IncomingWebhook for Stripe { let signature = security_header_kvs .remove("v1") - .ok_or(errors::ConnectorError::WebhookSignatureNotFound) - .into_report()?; + .ok_or(errors::ConnectorError::WebhookSignatureNotFound)?; - hex::decode(signature) - .into_report() - .change_context(errors::ConnectorError::WebhookSignatureNotFound) + hex::decode(signature).change_context(errors::ConnectorError::WebhookSignatureNotFound) } fn get_webhook_source_verification_message( @@ -1973,8 +1966,7 @@ impl api::IncomingWebhook for Stripe { let timestamp = security_header_kvs .remove("t") - .ok_or(errors::ConnectorError::WebhookSignatureNotFound) - .into_report()?; + .ok_or(errors::ConnectorError::WebhookSignatureNotFound)?; Ok(format!( "{}.{}", diff --git a/crates/router/src/connector/stripe/transformers.rs b/crates/router/src/connector/stripe/transformers.rs index 860065b2b03..95d9b6dd906 100644 --- a/crates/router/src/connector/stripe/transformers.rs +++ b/crates/router/src/connector/stripe/transformers.rs @@ -8,7 +8,7 @@ use common_utils::{ request::RequestContent, }; use data_models::mandates::AcceptanceType; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use masking::{ExposeInterface, ExposeOptionInterface, PeekInterface, Secret}; use serde::{Deserialize, Serialize}; use serde_json::Value; @@ -915,15 +915,15 @@ fn validate_shipping_address_against_payment_method( if !missing_fields.is_empty() { return Err(errors::ConnectorError::MissingRequiredFields { field_names: missing_fields, - }) - .into_report(); + } + .into()); } Ok(()) } None => Err(errors::ConnectorError::MissingRequiredField { field_name: "shipping.address", - }) - .into_report(), + } + .into()), }, _ => Ok(()), } diff --git a/crates/router/src/connector/threedsecureio.rs b/crates/router/src/connector/threedsecureio.rs index 818f2ebcec0..ecb80433594 100644 --- a/crates/router/src/connector/threedsecureio.rs +++ b/crates/router/src/connector/threedsecureio.rs @@ -2,7 +2,7 @@ pub mod transformers; use std::fmt::Debug; -use error_stack::{IntoReport, ResultExt}; +use error_stack::{report, ResultExt}; use masking::ExposeInterface; use pm_auth::consts; use transformers as threedsecureio; @@ -192,21 +192,21 @@ impl api::IncomingWebhook for Threedsecureio { &self, _request: &api::IncomingWebhookRequestDetails<'_>, ) -> CustomResult { - Err(errors::ConnectorError::WebhooksNotImplemented).into_report() + Err(report!(errors::ConnectorError::WebhooksNotImplemented)) } fn get_webhook_event_type( &self, _request: &api::IncomingWebhookRequestDetails<'_>, ) -> CustomResult { - Err(errors::ConnectorError::WebhooksNotImplemented).into_report() + Err(report!(errors::ConnectorError::WebhooksNotImplemented)) } fn get_webhook_resource_object( &self, _request: &api::IncomingWebhookRequestDetails<'_>, ) -> CustomResult, errors::ConnectorError> { - Err(errors::ConnectorError::WebhooksNotImplemented).into_report() + Err(report!(errors::ConnectorError::WebhooksNotImplemented)) } } diff --git a/crates/router/src/connector/threedsecureio/transformers.rs b/crates/router/src/connector/threedsecureio/transformers.rs index 42a453f5ce9..2d662e5e30f 100644 --- a/crates/router/src/connector/threedsecureio/transformers.rs +++ b/crates/router/src/connector/threedsecureio/transformers.rs @@ -3,7 +3,7 @@ use std::str::FromStr; use api_models::payments::{DeviceChannel, ThreeDsCompletionIndicator}; use base64::Engine; use common_utils::date_time; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use iso_currency::Currency; use isocountry; use masking::{ExposeInterface, Secret}; @@ -86,7 +86,6 @@ impl "threeDSServerTransID": pre_authn_response.threeds_server_trans_id, }); let three_ds_method_data_str = to_string(&three_ds_method_data) - .into_report() .change_context(errors::ConnectorError::ResponseDeserializationFailed) .attach_printable("error while constructing three_ds_method_data_str")?; let three_ds_method_data_base64 = BASE64_ENGINE.encode(three_ds_method_data_str); @@ -167,7 +166,6 @@ impl "challengeWindowSize": "01", }); let creq_str = to_string(&creq) - .into_report() .change_context(errors::ConnectorError::ResponseDeserializationFailed) .attach_printable("error while constructing creq_str")?; let creq_base64 = base64::Engine::encode(&BASE64_ENGINE, creq_str) @@ -283,11 +281,9 @@ impl TryFrom<&ThreedsecureioRouterData<&types::authentication::ConnectorAuthenti .currency .map(|currency| currency.to_string()) .ok_or(errors::ConnectorError::RequestEncodingFailed) - .into_report() .attach_printable("missing field currency")?; let purchase_currency: Currency = iso_currency::Currency::from_code(¤cy) .ok_or(errors::ConnectorError::RequestEncodingFailed) - .into_report() .attach_printable("error while parsing Currency")?; let billing_address = request.billing_address.address.clone().ok_or( errors::ConnectorError::MissingRequiredField { @@ -303,7 +299,6 @@ impl TryFrom<&ThreedsecureioRouterData<&types::authentication::ConnectorAuthenti })? .to_string(), ) - .into_report() .change_context(errors::ConnectorError::RequestEncodingFailed) .attach_printable("Error parsing billing_address.address.country")?; let connector_meta_data: ThreeDSecureIoMetaData = item @@ -345,7 +340,6 @@ impl TryFrom<&ThreedsecureioRouterData<&types::authentication::ConnectorAuthenti .return_url .clone() .ok_or(errors::ConnectorError::RequestEncodingFailed) - .into_report() .attach_printable("missing return_url")?, three_dscomp_ind: ThreeDSecureIoThreeDsCompletionIndicator::from( request.threeds_method_comp_ind.clone(), @@ -426,7 +420,6 @@ impl TryFrom<&ThreedsecureioRouterData<&types::authentication::ConnectorAuthenti purchase_exponent: purchase_currency .exponent() .ok_or(errors::ConnectorError::RequestEncodingFailed) - .into_report() .attach_printable("missing purchase_exponent")? .to_string(), purchase_date: date_time::DateTime::::from(date_time::now()) diff --git a/crates/router/src/connector/trustpay.rs b/crates/router/src/connector/trustpay.rs index 116cea9e239..ed4978743dd 100644 --- a/crates/router/src/connector/trustpay.rs +++ b/crates/router/src/connector/trustpay.rs @@ -6,7 +6,7 @@ use base64::Engine; use common_utils::{ crypto, errors::ReportSwitchExt, ext_traits::ByteSliceExt, request::RequestContent, }; -use error_stack::{IntoReport, Report, ResultExt}; +use error_stack::{Report, ResultExt}; use masking::PeekInterface; use transformers as trustpay; @@ -942,7 +942,6 @@ impl api::IncomingWebhook for Trustpay { .parse_struct("TrustpayWebhookResponse") .switch()?; hex::decode(response.signature) - .into_report() .change_context(errors::ConnectorError::WebhookSignatureNotFound) } diff --git a/crates/router/src/connector/tsys.rs b/crates/router/src/connector/tsys.rs index 10e5af8de22..9387fbcec1e 100644 --- a/crates/router/src/connector/tsys.rs +++ b/crates/router/src/connector/tsys.rs @@ -4,7 +4,7 @@ use std::fmt::Debug; use common_utils::request::RequestContent; use diesel_models::enums; -use error_stack::{IntoReport, ResultExt}; +use error_stack::{report, ResultExt}; use transformers as tsys; use crate::{ @@ -635,20 +635,20 @@ impl api::IncomingWebhook for Tsys { &self, _request: &api::IncomingWebhookRequestDetails<'_>, ) -> CustomResult { - Err(errors::ConnectorError::WebhooksNotImplemented).into_report() + Err(report!(errors::ConnectorError::WebhooksNotImplemented)) } fn get_webhook_event_type( &self, _request: &api::IncomingWebhookRequestDetails<'_>, ) -> CustomResult { - Err(errors::ConnectorError::WebhooksNotImplemented).into_report() + Err(report!(errors::ConnectorError::WebhooksNotImplemented)) } fn get_webhook_resource_object( &self, _request: &api::IncomingWebhookRequestDetails<'_>, ) -> CustomResult, errors::ConnectorError> { - Err(errors::ConnectorError::WebhooksNotImplemented).into_report() + Err(report!(errors::ConnectorError::WebhooksNotImplemented)) } } diff --git a/crates/router/src/connector/utils.rs b/crates/router/src/connector/utils.rs index a41c05f19be..89b88243057 100644 --- a/crates/router/src/connector/utils.rs +++ b/crates/router/src/connector/utils.rs @@ -12,7 +12,7 @@ use common_utils::{ }; use data_models::payments::payment_attempt::PaymentAttempt; use diesel_models::enums; -use error_stack::{report, IntoReport, ResultExt}; +use error_stack::{report, ResultExt}; use masking::{ExposeInterface, Secret}; use once_cell::sync::Lazy; use regex::Regex; @@ -657,7 +657,6 @@ impl PaymentsSyncRequestData for types::PaymentsSyncData { _ => Err(errors::ValidationError::IncorrectValueProvided { field_name: "connector_transaction_id", }) - .into_report() .attach_printable("Expected connector transaction ID not found") .change_context(errors::ConnectorError::MissingConnectorTransactionID)?, } @@ -868,7 +867,6 @@ impl CardData for api::Card { .peek() .clone() .parse::() - .into_report() .change_context(errors::ConnectorError::ResponseDeserializationFailed) .map(Secret::new) } @@ -877,7 +875,6 @@ impl CardData for api::Card { .peek() .clone() .parse::() - .into_report() .change_context(errors::ConnectorError::ResponseDeserializationFailed) .map(Secret::new) } @@ -888,7 +885,6 @@ fn get_card_issuer(card_number: &str) -> Result { for (k, v) in CARD_REGEX.iter() { let regex: Regex = v .clone() - .into_report() .change_context(errors::ConnectorError::RequestEncodingFailed)?; if regex.is_match(card_number) { return Ok(*k); @@ -920,7 +916,6 @@ impl WalletData for api::WalletData { T: serde::de::DeserializeOwned, { serde_json::from_str::(self.get_wallet_token()?.peek()) - .into_report() .change_context(errors::ConnectorError::InvalidWalletToken { wallet_name }) } @@ -929,11 +924,11 @@ impl WalletData for api::WalletData { Self::GooglePay(_) => { let json_token: serde_json::Value = self.get_wallet_token_as_json("Google Pay".to_owned())?; - let token_as_vec = serde_json::to_vec(&json_token) - .into_report() - .change_context(errors::ConnectorError::InvalidWalletToken { + let token_as_vec = serde_json::to_vec(&json_token).change_context( + errors::ConnectorError::InvalidWalletToken { wallet_name: "Google Pay".to_string(), - })?; + }, + )?; let encoded_token = consts::BASE64_ENGINE.encode(token_as_vec); Ok(encoded_token) } @@ -954,12 +949,10 @@ impl ApplePay for payments::ApplePayWalletData { String::from_utf8( consts::BASE64_ENGINE .decode(&self.payment_data) - .into_report() .change_context(errors::ConnectorError::InvalidWalletToken { wallet_name: "Apple Pay".to_string(), })?, ) - .into_report() .change_context(errors::ConnectorError::InvalidWalletToken { wallet_name: "Apple Pay".to_string(), })?, @@ -1157,7 +1150,6 @@ impl MandateData for payments::MandateAmountData { "mandate_data.mandate_type.{multi_use|single_use}.end_date", ))?; date_time::format_date(date, format) - .into_report() .change_context(errors::ConnectorError::DateFormattingFailed) } fn get_metadata(&self) -> Result { @@ -1216,7 +1208,6 @@ fn get_header_field( .map(|header_value| { header_value .to_str() - .into_report() .change_context(errors::ConnectorError::WebhookSignatureNotFound) }) .ok_or(report!( @@ -1270,7 +1261,6 @@ impl common_utils::errors::ErrorSwitch for errors::Parsi pub fn base64_decode(data: String) -> Result, Error> { consts::BASE64_ENGINE .decode(data) - .into_report() .change_context(errors::ConnectorError::ResponseDeserializationFailed) } @@ -1307,7 +1297,6 @@ pub fn get_amount_as_f64( let amount = match currency_unit { types::api::CurrencyUnit::Base => to_currency_base_unit_asf64(amount, currency)?, types::api::CurrencyUnit::Minor => u32::try_from(amount) - .into_report() .change_context(errors::ConnectorError::ParsingFailed)? .into(), }; @@ -1320,7 +1309,6 @@ pub fn to_currency_base_unit( ) -> Result> { currency .to_currency_base_unit(amount) - .into_report() .change_context(errors::ConnectorError::ParsingFailed) } @@ -1330,7 +1318,6 @@ pub fn to_currency_lower_unit( ) -> Result> { currency .to_currency_lower_unit(amount) - .into_report() .change_context(errors::ConnectorError::ResponseHandlingFailed) } @@ -1359,7 +1346,6 @@ pub fn to_currency_base_unit_with_zero_decimal_check( ) -> Result> { currency .to_currency_base_unit_with_zero_decimal_check(amount) - .into_report() .change_context(errors::ConnectorError::RequestEncodingFailed) } @@ -1369,7 +1355,6 @@ pub fn to_currency_base_unit_asf64( ) -> Result> { currency .to_currency_base_unit_asf64(amount) - .into_report() .change_context(errors::ConnectorError::ParsingFailed) } diff --git a/crates/router/src/connector/volt.rs b/crates/router/src/connector/volt.rs index 4a08bc1ad6b..9dc99e7881c 100644 --- a/crates/router/src/connector/volt.rs +++ b/crates/router/src/connector/volt.rs @@ -3,7 +3,7 @@ pub mod transformers; use std::fmt::Debug; use common_utils::{crypto, ext_traits::ByteSliceExt, request::RequestContent}; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use masking::{ExposeInterface, PeekInterface}; use transformers as volt; @@ -642,7 +642,6 @@ impl api::IncomingWebhook for Volt { .change_context(errors::ConnectorError::WebhookSignatureNotFound)?; hex::decode(signature) - .into_report() .change_context(errors::ConnectorError::WebhookVerificationSecretInvalid) } diff --git a/crates/router/src/connector/wise.rs b/crates/router/src/connector/wise.rs index 152786b46a3..e4a49d7c566 100644 --- a/crates/router/src/connector/wise.rs +++ b/crates/router/src/connector/wise.rs @@ -3,7 +3,7 @@ use std::fmt::Debug; #[cfg(feature = "payouts")] use common_utils::request::RequestContent; -use error_stack::{IntoReport, ResultExt}; +use error_stack::{report, ResultExt}; #[cfg(feature = "payouts")] use masking::PeekInterface; #[cfg(feature = "payouts")] @@ -748,20 +748,20 @@ impl api::IncomingWebhook for Wise { &self, _request: &api::IncomingWebhookRequestDetails<'_>, ) -> CustomResult { - Err(errors::ConnectorError::WebhooksNotImplemented).into_report() + Err(report!(errors::ConnectorError::WebhooksNotImplemented)) } fn get_webhook_event_type( &self, _request: &api::IncomingWebhookRequestDetails<'_>, ) -> CustomResult { - Err(errors::ConnectorError::WebhooksNotImplemented).into_report() + Err(report!(errors::ConnectorError::WebhooksNotImplemented)) } fn get_webhook_resource_object( &self, _request: &api::IncomingWebhookRequestDetails<'_>, ) -> CustomResult, errors::ConnectorError> { - Err(errors::ConnectorError::WebhooksNotImplemented).into_report() + Err(report!(errors::ConnectorError::WebhooksNotImplemented)) } } diff --git a/crates/router/src/connector/worldline.rs b/crates/router/src/connector/worldline.rs index 410d096d20a..ae5e6c1b4a3 100644 --- a/crates/router/src/connector/worldline.rs +++ b/crates/router/src/connector/worldline.rs @@ -5,7 +5,7 @@ use std::fmt::Debug; use base64::Engine; use common_utils::{ext_traits::ByteSliceExt, request::RequestContent}; use diesel_models::enums; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use masking::{ExposeInterface, PeekInterface}; use ring::hmac; use time::{format_description, OffsetDateTime}; @@ -65,11 +65,9 @@ impl Worldline { let format = format_description::parse( "[weekday repr:short], [day] [month repr:short] [year] [hour]:[minute]:[second] GMT", ) - .into_report() .change_context(errors::ConnectorError::InvalidDateFormat)?; OffsetDateTime::now_utc() .format(&format) - .into_report() .change_context(errors::ConnectorError::InvalidDateFormat) } } @@ -575,12 +573,11 @@ impl ConnectorIntegration, ) -> CustomResult { || -> _ { - Ok(api_models::webhooks::ObjectReferenceId::PaymentId( - api_models::payments::PaymentIdType::ConnectorTransactionId( - request - .body - .parse_struct::("WorldlineWebhookEvent")? - .payment - .parse_value::("WorldlineWebhookObjectId")? - .id, + Ok::<_, error_stack::Report>( + api_models::webhooks::ObjectReferenceId::PaymentId( + api_models::payments::PaymentIdType::ConnectorTransactionId( + request + .body + .parse_struct::("WorldlineWebhookEvent")? + .payment + .parse_value::("WorldlineWebhookObjectId")? + .id, + ), ), - )) + ) }() .change_context(errors::ConnectorError::WebhookReferenceIdNotFound) } @@ -866,7 +862,6 @@ impl api::IncomingWebhook for Worldline { Some(header_value) => { let verification_signature_value = header_value .to_str() - .into_report() .change_context(errors::ConnectorError::WebhookResponseEncodingFailed)? .to_string(); services::api::ApplicationResponse::TextPlain(verification_signature_value) diff --git a/crates/router/src/connector/worldpay.rs b/crates/router/src/connector/worldpay.rs index 65d4d2553e5..1f2dac807d1 100644 --- a/crates/router/src/connector/worldpay.rs +++ b/crates/router/src/connector/worldpay.rs @@ -6,7 +6,7 @@ use std::fmt::Debug; use common_utils::{crypto, ext_traits::ByteSliceExt, request::RequestContent}; use diesel_models::enums; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use transformers as worldpay; use self::{requests::*, response::*}; @@ -73,8 +73,7 @@ impl ConnectorCommon for Worldpay { &self, auth_type: &types::ConnectorAuthType, ) -> CustomResult)>, errors::ConnectorError> { - let auth: worldpay::WorldpayAuthType = auth_type - .try_into() + let auth = worldpay::WorldpayAuthType::try_from(auth_type) .change_context(errors::ConnectorError::FailedToObtainAuthType)?; Ok(vec![( headers::AUTHORIZATION.to_string(), @@ -722,9 +721,7 @@ impl api::IncomingWebhook for Worldpay { .split('/') .last() .ok_or(errors::ConnectorError::WebhookSignatureNotFound)?; - hex::decode(signature) - .into_report() - .change_context(errors::ConnectorError::WebhookResponseEncodingFailed) + hex::decode(signature).change_context(errors::ConnectorError::WebhookResponseEncodingFailed) } fn get_webhook_source_verification_message( @@ -734,13 +731,11 @@ impl api::IncomingWebhook for Worldpay { connector_webhook_secrets: &api_models::webhooks::ConnectorWebhookSecrets, ) -> CustomResult, errors::ConnectorError> { let secret_str = std::str::from_utf8(&connector_webhook_secrets.secret) - .into_report() .change_context(errors::ConnectorError::WebhookBodyDecodingFailed)?; let to_sign = format!( "{}{}", secret_str, std::str::from_utf8(request.body) - .into_report() .change_context(errors::ConnectorError::WebhookBodyDecodingFailed)? ); Ok(to_sign.into_bytes()) diff --git a/crates/router/src/connector/zen.rs b/crates/router/src/connector/zen.rs index 537e97cb577..7c28dfcc43a 100644 --- a/crates/router/src/connector/zen.rs +++ b/crates/router/src/connector/zen.rs @@ -3,7 +3,7 @@ pub mod transformers; use std::fmt::Debug; use common_utils::{crypto, ext_traits::ByteSliceExt, request::RequestContent}; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use masking::PeekInterface; use transformers as zen; use uuid::Uuid; @@ -582,9 +582,7 @@ impl api::IncomingWebhook for Zen { .parse_struct("ZenWebhookSignature") .change_context(errors::ConnectorError::WebhookSignatureNotFound)?; let signature = webhook_body.hash; - hex::decode(signature) - .into_report() - .change_context(errors::ConnectorError::WebhookSignatureNotFound) + hex::decode(signature).change_context(errors::ConnectorError::WebhookSignatureNotFound) } fn get_webhook_source_verification_message( @@ -688,7 +686,6 @@ impl api::IncomingWebhook for Zen { request: &api::IncomingWebhookRequestDetails<'_>, ) -> CustomResult, errors::ConnectorError> { let reference_object: serde_json::Value = serde_json::from_slice(request.body) - .into_report() .change_context(errors::ConnectorError::WebhookResourceObjectNotFound)?; Ok(Box::new(reference_object)) } diff --git a/crates/router/src/core/admin.rs b/crates/router/src/core/admin.rs index a4be66242ee..f48227b926e 100644 --- a/crates/router/src/core/admin.rs +++ b/crates/router/src/core/admin.rs @@ -11,7 +11,7 @@ use common_utils::{ pii, }; use diesel_models::configs; -use error_stack::{report, FutureExt, IntoReport, ResultExt}; +use error_stack::{report, FutureExt, ResultExt}; use futures::future::try_join_all; use masking::{PeekInterface, Secret}; use pm_auth::connector::plaid::transformers::PlaidAuthType; @@ -175,7 +175,7 @@ pub async fn create_merchant_account( }; let mut merchant_account = async { - Ok(domain::MerchantAccount { + Ok::<_, error_stack::Report>(domain::MerchantAccount { merchant_id: req.merchant_id, merchant_name: req .merchant_name @@ -279,8 +279,7 @@ pub async fn create_merchant_account( .ok(); Ok(service_api::ApplicationResponse::Json( - merchant_account - .try_into() + api::MerchantAccountResponse::try_from(merchant_account) .change_context(errors::ApiErrorResponse::InternalServerError) .attach_printable("Failed while generating response")?, )) @@ -300,11 +299,11 @@ pub async fn list_merchant_account( let merchant_accounts = merchant_accounts .into_iter() .map(|merchant_account| { - merchant_account - .try_into() - .change_context(errors::ApiErrorResponse::InvalidDataValue { + api::MerchantAccountResponse::try_from(merchant_account).change_context( + errors::ApiErrorResponse::InvalidDataValue { field_name: "merchant_account", - }) + }, + ) }) .collect::, _>>()?; @@ -330,8 +329,7 @@ pub async fn get_merchant_account( .to_not_found_response(errors::ApiErrorResponse::MerchantAccountNotFound)?; Ok(service_api::ApplicationResponse::Json( - merchant_account - .try_into() + api::MerchantAccountResponse::try_from(merchant_account) .change_context(errors::ApiErrorResponse::InternalServerError) .attach_printable("Failed to construct response")?, )) @@ -609,8 +607,7 @@ pub async fn merchant_account_update( // If there are any new business labels generated, create business profile Ok(service_api::ApplicationResponse::Json( - response - .try_into() + api::MerchantAccountResponse::try_from(response) .change_context(errors::ApiErrorResponse::InternalServerError) .attach_printable("Failed while generating response")?, )) @@ -796,22 +793,21 @@ pub async fn create_payment_connector( if req.connector_type != api_enums::ConnectorType::PaymentMethodAuth { return Err(errors::ApiErrorResponse::InvalidRequestData { message: "Invalid connector type given".to_string(), - }) - .into_report(); + } + .into()); } } else if authentication_connector.is_some() { if req.connector_type != api_enums::ConnectorType::AuthenticationProcessor { return Err(errors::ApiErrorResponse::InvalidRequestData { message: "Invalid connector type given".to_string(), - }) - .into_report(); + } + .into()); } } else { let routable_connector_option = req .connector_name .to_string() - .parse() - .into_report() + .parse::() .change_context(errors::ApiErrorResponse::InvalidRequestData { message: "Invalid connector name given".to_string(), })?; @@ -1047,7 +1043,6 @@ async fn validate_pm_auth( profile_id: &Option, ) -> RouterResponse<()> { let config = serde_json::from_value::(val) - .into_report() .change_context(errors::ApiErrorResponse::InvalidRequestData { message: "invalid data received for payment method auth config".to_string(), }) @@ -1071,15 +1066,14 @@ async fn validate_pm_auth( .find(|mca| mca.merchant_connector_id == conn_choice.mca_id) .ok_or(errors::ApiErrorResponse::GenericNotFoundError { message: "payment method auth connector account not found".to_string(), - }) - .into_report()?; + })?; if &pm_auth_mca.profile_id != profile_id { return Err(errors::ApiErrorResponse::GenericNotFoundError { message: "payment method auth profile_id differs from connector profile_id" .to_string(), - }) - .into_report(); + } + .into()); } } @@ -1205,7 +1199,6 @@ pub async fn update_payment_connector( let metadata = req.metadata.clone().or(mca.metadata.clone()); let connector_name = mca.connector_name.as_ref(); let connector_enum = api_models::enums::Connector::from_str(connector_name) - .into_report() .change_context(errors::ApiErrorResponse::InvalidDataValue { field_name: "connector", }) @@ -1297,7 +1290,6 @@ pub async fn update_payment_connector( .profile_id .clone() .ok_or(errors::ApiErrorResponse::InternalServerError) - .into_report() .attach_printable("Missing `profile_id` in merchant connector account")?; let request_connector_label = req.connector_label; diff --git a/crates/router/src/core/api_keys.rs b/crates/router/src/core/api_keys.rs index 738d9d0c87a..f75ed011688 100644 --- a/crates/router/src/core/api_keys.rs +++ b/crates/router/src/core/api_keys.rs @@ -1,7 +1,7 @@ use common_utils::date_time; #[cfg(feature = "email")] use diesel_models::{api_keys::ApiKey, enums as storage_enums}; -use error_stack::{report, IntoReport, ResultExt}; +use error_stack::{report, ResultExt}; use masking::{PeekInterface, StrongSecret}; use router_env::{instrument, tracing}; @@ -33,12 +33,10 @@ impl settings::ApiKeys { HASH_KEY.get_or_try_init(|| { <[u8; PlaintextApiKey::HASH_KEY_LEN]>::try_from( hex::decode(self.hash_key.peek()) - .into_report() .change_context(errors::ApiErrorResponse::InternalServerError) .attach_printable("API key hash key has invalid hexadecimal data")? .as_slice(), ) - .into_report() .change_context(errors::ApiErrorResponse::InternalServerError) .attach_printable("The API hashing key has incorrect length") .map(StrongSecret::new) @@ -165,7 +163,6 @@ pub async fn create_api_key( add_api_key_expiry_task(store, &api_key, expiry_reminder_days) .await - .into_report() .change_context(errors::ApiErrorResponse::InternalServerError) .attach_printable("Failed to insert API key expiry reminder to process tracker")?; } @@ -197,7 +194,6 @@ pub async fn add_api_key_expiry_task( }) }) .ok_or(errors::ApiErrorResponse::InternalServerError) - .into_report() .attach_printable("Failed to obtain initial process tracker schedule time")?; if schedule_time <= current_time { @@ -302,7 +298,6 @@ pub async fn update_api_key( // Process exist in process, update the process with new schedule_time update_api_key_expiry_task(store, &api_key, expiry_reminder_days) .await - .into_report() .change_context(errors::ApiErrorResponse::InternalServerError) .attach_printable( "Failed to update API key expiry reminder task in process tracker", @@ -313,7 +308,6 @@ pub async fn update_api_key( // Process exist in process, revoke it revoke_api_key_expiry_task(store, &key_id) .await - .into_report() .change_context(errors::ApiErrorResponse::InternalServerError) .attach_printable( "Failed to revoke API key expiry reminder task in process tracker", @@ -327,7 +321,6 @@ pub async fn update_api_key( // schedule_time based on new expiry set. add_api_key_expiry_task(store, &api_key, expiry_reminder_days) .await - .into_report() .change_context(errors::ApiErrorResponse::InternalServerError) .attach_printable( "Failed to insert API key expiry reminder task to process tracker", @@ -378,7 +371,6 @@ pub async fn update_api_key_expiry_task( }; let updated_api_key_expiry_workflow_model = serde_json::to_value(updated_tracking_data) - .into_report() .change_context(errors::ApiErrorResponse::InternalServerError) .attach_printable_lazy(|| { format!("unable to serialize API key expiry tracker: {updated_tracking_data:?}") @@ -432,7 +424,6 @@ pub async fn revoke_api_key( if existing_process_tracker_task.is_some() { revoke_api_key_expiry_task(store, key_id) .await - .into_report() .change_context(errors::ApiErrorResponse::InternalServerError) .attach_printable( "Failed to revoke API key expiry reminder task in process tracker", diff --git a/crates/router/src/core/api_locking.rs b/crates/router/src/core/api_locking.rs index b5c3f8ae53e..ec205f52427 100644 --- a/crates/router/src/core/api_locking.rs +++ b/crates/router/src/core/api_locking.rs @@ -1,7 +1,7 @@ use std::fmt::Debug; use actix_web::rt::time as actix_time; -use error_stack::{IntoReport, ResultExt}; +use error_stack::{report, ResultExt}; use redis_interface as redis; use router_env::{instrument, logger, tracing}; @@ -102,7 +102,7 @@ impl LockAction { } } - Err(errors::ApiErrorResponse::ResourceBusy).into_report() + Err(report!(errors::ApiErrorResponse::ResourceBusy)) } Self::QueueWithOk | Self::Drop | Self::NotApplicable => Ok(()), } @@ -135,19 +135,18 @@ impl LockAction { .record("redis_lock_released", redis_locking_key); Ok(()) } - Ok(redis::types::DelReply::KeyNotDeleted) => Err( - errors::ApiErrorResponse::InternalServerError, - ) - .into_report() - .attach_printable( - "Status release lock called but key is not found in redis", - ), + Ok(redis::types::DelReply::KeyNotDeleted) => { + Err(errors::ApiErrorResponse::InternalServerError) + .attach_printable( + "Status release lock called but key is not found in redis", + ) + } Err(error) => Err(error) .change_context(errors::ApiErrorResponse::InternalServerError), } } else { Err(errors::ApiErrorResponse::InternalServerError) - .into_report().attach_printable("The request_id which acquired the lock is not equal to the request_id requesting for releasing the lock") + .attach_printable("The request_id which acquired the lock is not equal to the request_id requesting for releasing the lock") } } Err(error) => { diff --git a/crates/router/src/core/authentication.rs b/crates/router/src/core/authentication.rs index fa77ac1b5da..09d8ccc8833 100644 --- a/crates/router/src/core/authentication.rs +++ b/crates/router/src/core/authentication.rs @@ -6,7 +6,7 @@ pub mod types; use api_models::payments; use common_enums::Currency; use common_utils::{errors::CustomResult, ext_traits::ValueExt}; -use error_stack::ResultExt; +use error_stack::{report, ResultExt}; use masking::PeekInterface; use super::errors; @@ -99,7 +99,7 @@ pub async fn perform_authentication( } } }), - _ => Err(errors::ApiErrorResponse::InternalServerError.into()) + _ => Err(report!(errors::ApiErrorResponse::InternalServerError)) .attach_printable("unexpected response in authentication flow")?, } } diff --git a/crates/router/src/core/blocklist/utils.rs b/crates/router/src/core/blocklist/utils.rs index 68cdb2690b7..7c01a9aca76 100644 --- a/crates/router/src/core/blocklist/utils.rs +++ b/crates/router/src/core/blocklist/utils.rs @@ -2,7 +2,7 @@ use api_models::blocklist as api_blocklist; use common_enums::MerchantDecision; use common_utils::errors::CustomResult; use diesel_models::configs; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use masking::StrongSecret; use super::{errors, transformers::generate_fingerprint, AppState}; @@ -120,8 +120,8 @@ fn validate_card_bin(bin: &str) -> RouterResult<()> { Err(errors::ApiErrorResponse::InvalidDataFormat { field_name: "data".to_string(), expected_format: "a 6 digit number".to_string(), - }) - .into_report() + } + .into()) } } @@ -132,8 +132,8 @@ fn validate_extended_card_bin(bin: &str) -> RouterResult<()> { Err(errors::ApiErrorResponse::InvalidDataFormat { field_name: "data".to_string(), expected_format: "an 8 digit number".to_string(), - }) - .into_report() + } + .into()) } } @@ -176,8 +176,8 @@ pub async fn insert_entry_into_blocklist( return Err(errors::ApiErrorResponse::PreconditionFailed { message: "data associated with the given fingerprint is already blocked" .to_string(), - }) - .into_report(); + } + .into()); } // if it is a db not found error, we can proceed as normal @@ -259,8 +259,8 @@ async fn duplicate_check_insert_bin( Ok(_) => { return Err(errors::ApiErrorResponse::PreconditionFailed { message: "provided bin is already blocked".to_string(), - }) - .into_report(); + } + .into()); } Err(e) if e.current_context().is_db_not_found() => {} diff --git a/crates/router/src/core/conditional_config.rs b/crates/router/src/core/conditional_config.rs index 26789470c20..c352e825052 100644 --- a/crates/router/src/core/conditional_config.rs +++ b/crates/router/src/core/conditional_config.rs @@ -4,7 +4,7 @@ use api_models::{ }; use common_utils::ext_traits::{Encode, StringExt, ValueExt}; use diesel_models::configs; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use euclid::frontend::ast; use super::routing::helpers::{ @@ -65,7 +65,6 @@ pub async fn upsert_conditional_config( let read_config_key = db.find_config_by_key(&key).await; ast::lowering::lower_program(prog.clone()) - .into_report() .change_context(errors::ApiErrorResponse::InvalidRequestData { message: "Invalid Request Data".to_string(), }) diff --git a/crates/router/src/core/connector_onboarding/paypal.rs b/crates/router/src/core/connector_onboarding/paypal.rs index 4c1f16e9135..616fcbdc8cc 100644 --- a/crates/router/src/core/connector_onboarding/paypal.rs +++ b/crates/router/src/core/connector_onboarding/paypal.rs @@ -1,6 +1,6 @@ use api_models::{admin::MerchantConnectorUpdate, connector_onboarding as api}; use common_utils::ext_traits::Encode; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use masking::{ExposeInterface, PeekInterface, Secret}; use crate::{ @@ -55,7 +55,6 @@ pub async fn get_action_url_from_paypal( let parsed_response: types::paypal::PartnerReferralResponse = referral_response .json() .await - .into_report() .change_context(ApiErrorResponse::InternalServerError) .attach_printable("Failed to parse paypal response")?; @@ -106,7 +105,6 @@ pub async fn sync_merchant_onboarding_status( let parsed_response: types::paypal::SellerStatusDetailsResponse = merchant_details_response .json() .await - .into_report() .change_context(ApiErrorResponse::InternalServerError) .attach_printable("Failed to parse paypal merchant details response")?; @@ -133,7 +131,6 @@ async fn find_paypal_merchant_by_tracking_id( seller_status_response .json() .await - .into_report() .change_context(ApiErrorResponse::InternalServerError) .attach_printable("Failed to parse paypal onboarding status response")?, )); diff --git a/crates/router/src/core/customers.rs b/crates/router/src/core/customers.rs index 02127efe6de..732596d5c1c 100644 --- a/crates/router/src/core/customers.rs +++ b/crates/router/src/core/customers.rs @@ -2,7 +2,7 @@ use common_utils::{ crypto::{Encryptable, GcmAes256}, errors::ReportSwitchExt, }; -use error_stack::{IntoReport, ResultExt}; +use error_stack::{report, ResultExt}; use masking::ExposeInterface; use router_env::{instrument, tracing}; @@ -55,7 +55,9 @@ pub async fn create_customer( Ok(()) } } - Ok(_) => Err(errors::CustomersErrorResponse::CustomerAlreadyExists).into_report(), + Ok(_) => Err(report!( + errors::CustomersErrorResponse::CustomerAlreadyExists + )), }?; let key = key_store.key.get_inner().peek(); diff --git a/crates/router/src/core/disputes.rs b/crates/router/src/core/disputes.rs index f53939a8f9d..4928dc949dc 100644 --- a/crates/router/src/core/disputes.rs +++ b/crates/router/src/core/disputes.rs @@ -1,6 +1,6 @@ use api_models::{disputes as dispute_models, files as files_api_models}; use common_utils::ext_traits::{Encode, ValueExt}; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use router_env::{instrument, tracing}; pub mod transformers; @@ -368,7 +368,6 @@ pub async fn attach_evidence( let file_id = match &create_file_response { services::ApplicationResponse::Json(res) => res.file_id.clone(), _ => Err(errors::ApiErrorResponse::InternalServerError) - .into_report() .attach_printable("Unexpected response received from files create core")?, }; let dispute_evidence: api::DisputeEvidence = dispute diff --git a/crates/router/src/core/files.rs b/crates/router/src/core/files.rs index d3f490a0a6c..e2ce5b42c3f 100644 --- a/crates/router/src/core/files.rs +++ b/crates/router/src/core/files.rs @@ -1,7 +1,7 @@ pub mod helpers; use api_models::files; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use super::errors::{self, RouterResponse}; use crate::{ @@ -118,13 +118,11 @@ pub async fn files_retrieve_core( let content_type = file_metadata_object .file_type .parse::() - .into_report() .change_context(errors::ApiErrorResponse::InternalServerError) .attach_printable("Failed to parse file content type")?; Ok(ApplicationResponse::FileData(( received_data .ok_or(errors::ApiErrorResponse::FileNotAvailable) - .into_report() .attach_printable("File data not found")?, content_type, ))) diff --git a/crates/router/src/core/files/helpers.rs b/crates/router/src/core/files/helpers.rs index 0a509b238af..0c6a88d8270 100644 --- a/crates/router/src/core/files/helpers.rs +++ b/crates/router/src/core/files/helpers.rs @@ -1,6 +1,6 @@ use actix_multipart::Field; use common_utils::errors::CustomResult; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use futures::TryStreamExt; use crate::{ @@ -97,7 +97,6 @@ pub async fn delete_file_using_file_id( ) { (Some(provider), Some(provider_file_id), true) => (provider, provider_file_id), _ => Err(errors::ApiErrorResponse::FileNotAvailable) - .into_report() .attach_printable("File not available")?, }; match provider { @@ -123,7 +122,6 @@ pub async fn retrieve_file_from_connector( file_metadata .file_upload_provider .ok_or(errors::ApiErrorResponse::InternalServerError) - .into_report() .attach_printable("Missing file upload provider")?, )? .to_string(); @@ -194,7 +192,6 @@ pub async fn retrieve_file_and_provider_file_id_from_file_id( ) { (Some(provider), Some(provider_file_id), true) => (provider, provider_file_id), _ => Err(errors::ApiErrorResponse::FileNotAvailable) - .into_report() .attach_printable("File not available")?, }; match provider { diff --git a/crates/router/src/core/fraud_check/operation/fraud_check_post.rs b/crates/router/src/core/fraud_check/operation/fraud_check_post.rs index 95349e44755..a6cd0976129 100644 --- a/crates/router/src/core/fraud_check/operation/fraud_check_post.rs +++ b/crates/router/src/core/fraud_check/operation/fraud_check_post.rs @@ -398,12 +398,10 @@ impl UpdateTracker for FraudCheckPost { last_step: frm_data.fraud_check.last_step, }; Some(fraud_check_update) - } }, }, - FrmResponse::Checkout(_) | FrmResponse::Transaction(_) => { Some(FraudCheckUpdate::ErrorUpdate { status: FraudCheckStatus::TransactionFailure, diff --git a/crates/router/src/core/gsm.rs b/crates/router/src/core/gsm.rs index 611a35d6363..668c1773e2c 100644 --- a/crates/router/src/core/gsm.rs +++ b/crates/router/src/core/gsm.rs @@ -1,6 +1,6 @@ use api_models::gsm as gsm_api_types; use diesel_models::gsm as storage; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use router_env::{instrument, tracing}; use crate::{ @@ -132,7 +132,6 @@ pub async fn delete_gsm_rule( )) } else { Err(errors::ApiErrorResponse::InternalServerError) - .into_report() .attach_printable("Failed while Deleting Gsm rule, got response as false") } } diff --git a/crates/router/src/core/mandate.rs b/crates/router/src/core/mandate.rs index 6f022c9fca9..0ad13f0703c 100644 --- a/crates/router/src/core/mandate.rs +++ b/crates/router/src/core/mandate.rs @@ -3,7 +3,7 @@ pub mod utils; use api_models::payments; use common_utils::ext_traits::Encode; use diesel_models::{enums as storage_enums, Mandate}; -use error_stack::{report, IntoReport, ResultExt}; +use error_stack::{report, ResultExt}; use futures::future; use router_env::{instrument, logger, tracing}; @@ -59,7 +59,7 @@ pub async fn revoke_mandate( .find_mandate_by_merchant_id_mandate_id(&merchant_account.merchant_id, &req.mandate_id) .await .to_not_found_response(errors::ApiErrorResponse::MandateNotFound)?; - let mandate_revoke_status = match mandate.mandate_status { + match mandate.mandate_status { common_enums::MandateStatus::Active | common_enums::MandateStatus::Inactive | common_enums::MandateStatus::Pending => { @@ -136,18 +136,17 @@ pub async fn revoke_mandate( connector: mandate.connector, status_code: err.status_code, reason: err.reason, - }) - .into_report(), + } + .into()), } } common_enums::MandateStatus::Revoked => { Err(errors::ApiErrorResponse::MandateValidationFailed { reason: "Mandate has already been revoked".to_string(), - }) - .into_report() + } + .into()) } - }; - mandate_revoke_status + } } #[instrument(skip(db))] @@ -261,7 +260,6 @@ where mandate_reference, .. }) => mandate_reference, Ok(_) => Err(errors::ApiErrorResponse::InternalServerError) - .into_report() .attach_printable("Unexpected response received")?, Err(_) => return Ok(resp), }; diff --git a/crates/router/src/core/payment_link.rs b/crates/router/src/core/payment_link.rs index 096d5c88743..722aad26c0d 100644 --- a/crates/router/src/core/payment_link.rs +++ b/crates/router/src/core/payment_link.rs @@ -6,7 +6,7 @@ use common_utils::{ }, ext_traits::{OptionExt, ValueExt}, }; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use futures::future; use masking::{PeekInterface, Secret}; use time::PrimitiveDateTime; @@ -93,7 +93,6 @@ pub async fn intiate_payment_link_flow( .profile_id .or(payment_intent.profile_id) .ok_or(errors::ApiErrorResponse::InternalServerError) - .into_report() .attach_printable("Profile id missing in payment link and payment intent")?; let business_profile = db @@ -120,7 +119,6 @@ pub async fn intiate_payment_link_flow( )?; let amount = currency .to_currency_base_unit(payment_intent.amount) - .into_report() .change_context(errors::ApiErrorResponse::CurrencyConversionFailed)?; let order_details = validate_order_details(payment_intent.order_details.clone(), currency)?; @@ -236,7 +234,6 @@ The get_js_script function is used to inject dynamic value to payment_link sdk, fn get_js_script(payment_details: api_models::payments::PaymentLinkData) -> RouterResult { let payment_details_str = serde_json::to_string(&payment_details) - .into_report() .change_context(errors::ApiErrorResponse::InternalServerError) .attach_printable("Failed to serialize PaymentLinkData")?; Ok(format!("window.__PAYMENT_DETAILS = {payment_details_str};")) @@ -336,10 +333,10 @@ fn validate_order_details( } else { order_details_amount_string.product_img_link = order.product_img_link.clone() }; - order_details_amount_string.amount = currency - .to_currency_base_unit(order.amount) - .into_report() - .change_context(errors::ApiErrorResponse::CurrencyConversionFailed)?; + order_details_amount_string.amount = + currency + .to_currency_base_unit(order.amount) + .change_context(errors::ApiErrorResponse::CurrencyConversionFailed)?; order_details_amount_string.product_name = capitalize_first_char(&order.product_name.clone()); order_details_amount_string.quantity = order.quantity; @@ -356,7 +353,6 @@ pub fn extract_payment_link_config( pl_config: serde_json::Value, ) -> Result> { serde_json::from_value::(pl_config.clone()) - .into_report() .change_context(errors::ApiErrorResponse::InvalidDataValue { field_name: "payment_link_config", }) @@ -522,7 +518,6 @@ pub async fn get_payment_link_status( let amount = currency .to_currency_base_unit(payment_attempt.net_amount) - .into_report() .change_context(errors::ApiErrorResponse::CurrencyConversionFailed)?; // converting first letter of merchant name to upperCase @@ -533,7 +528,6 @@ pub async fn get_payment_link_status( .profile_id .or(payment_intent.profile_id) .ok_or(errors::ApiErrorResponse::InternalServerError) - .into_report() .attach_printable("Profile id missing in payment link and payment intent")?; let business_profile = db diff --git a/crates/router/src/core/payment_methods/cards.rs b/crates/router/src/core/payment_methods/cards.rs index 2a6c29ce803..59215da32f1 100644 --- a/crates/router/src/core/payment_methods/cards.rs +++ b/crates/router/src/core/payment_methods/cards.rs @@ -28,7 +28,7 @@ use diesel_models::{ payment_method, }; use domain::CustomerUpdate; -use error_stack::{report, IntoReport, ResultExt}; +use error_stack::{report, ResultExt}; use masking::Secret; use router_env::{instrument, tracing}; use strum::IntoEnumIterator; @@ -510,7 +510,6 @@ pub async fn add_bank_to_locker( logger::error!("Error while encoding payout method data: {}", err); errors::VaultError::SavePaymentMethodFailed }) - .into_report() .change_context(errors::VaultError::SavePaymentMethodFailed) .attach_printable("Unable to encode payout method data") .ok() @@ -716,7 +715,6 @@ pub async fn decode_and_decrypt_locker_data( let key = key_store.key.get_inner().peek(); // Decode let decoded_bytes = hex::decode(&enc_card_data) - .into_report() .change_context(errors::VaultError::ResponseDeserializationFailed) .attach_printable("Failed to decode hex string into bytes")?; // Decrypt @@ -1025,10 +1023,7 @@ pub async fn mock_get_card<'a>( card_fingerprint: locker_mock_up.card_fingerprint.into(), card_global_fingerprint: locker_mock_up.card_global_fingerprint.into(), merchant_id: Some(locker_mock_up.merchant_id), - card_number: locker_mock_up - .card_number - .try_into() - .into_report() + card_number: cards::CardNumber::try_from(locker_mock_up.card_number) .change_context(errors::VaultError::ResponseDeserializationFailed) .attach_printable("Invalid card number format from the mock locker") .map(Some)?, @@ -1492,10 +1487,8 @@ pub async fn list_payment_methods( .connector .connector_name .to_string() - .parse() - .into_report() - .change_context(errors::ApiErrorResponse::InternalServerError) - .attach_printable("")?, + .parse::() + .change_context(errors::ApiErrorResponse::InternalServerError)?, #[cfg(feature = "connector_choice_mca_id")] merchant_connector_id: choice.connector.merchant_connector_id, #[cfg(not(feature = "connector_choice_mca_id"))] @@ -1540,7 +1533,6 @@ pub async fn list_payment_methods( .as_ref() .map(|config| { serde_json::from_value::(config.clone()) - .into_report() .change_context(errors::StorageError::DeserializationFailed) .attach_printable("Failed to deserialize Payment Method Auth config") }) @@ -1651,7 +1643,6 @@ pub async fn list_payment_methods( let connector = element.connector.clone(); let connector_variant = api_enums::Connector::from_str(connector.as_str()) - .into_report() .change_context(errors::ConnectorError::InvalidConnectorName) .change_context(errors::ApiErrorResponse::InvalidDataValue { field_name: "connector", @@ -2238,7 +2229,6 @@ pub async fn filter_payment_methods( ); let connector_variant = api_enums::Connector::from_str(connector.as_str()) - .into_report() .change_context(errors::ConnectorError::InvalidConnectorName) .change_context(errors::ApiErrorResponse::InvalidDataValue { field_name: "connector", @@ -3161,7 +3151,7 @@ async fn get_masked_bank_details( mask: bank_details.mask, })), }, - None => Err(errors::ApiErrorResponse::InternalServerError.into()) + None => Err(report!(errors::ApiErrorResponse::InternalServerError)) .attach_printable("Unable to fetch payment method data"), } } @@ -3191,8 +3181,8 @@ async fn get_bank_account_connector_details( Some(pmd) => match pmd { PaymentMethodsData::Card(_) => Err(errors::ApiErrorResponse::UnprocessableEntity { message: "Card is not a valid entity".to_string(), - }) - .into_report(), + } + .into()), PaymentMethodsData::BankDetails(bank_details) => { let connector_details = bank_details .connector_details @@ -3240,7 +3230,6 @@ pub async fn set_default_payment_method( Err(errors::ApiErrorResponse::PreconditionFailed { message: "The payment_method_id is not valid".to_string(), }) - .into_report() }, )?; @@ -3250,7 +3239,6 @@ pub async fn set_default_payment_method( Err(errors::ApiErrorResponse::PreconditionFailed { message: "Payment Method is already set as default".to_string(), }) - .into_report() }, )?; diff --git a/crates/router/src/core/payment_methods/surcharge_decision_configs.rs b/crates/router/src/core/payment_methods/surcharge_decision_configs.rs index 874e1bde32f..e89fb22e879 100644 --- a/crates/router/src/core/payment_methods/surcharge_decision_configs.rs +++ b/crates/router/src/core/payment_methods/surcharge_decision_configs.rs @@ -6,7 +6,7 @@ use api_models::{ surcharge_decision_configs::{self, SurchargeDecisionConfigs, SurchargeDecisionManagerRecord}, }; use common_utils::{ext_traits::StringExt, static_cache::StaticCache, types as common_utils_types}; -use error_stack::{self, IntoReport, ResultExt}; +use error_stack::{self, ResultExt}; use euclid::{ backend, backend::{inputs as dsl_inputs, EuclidBackend}, @@ -42,7 +42,6 @@ impl TryFrom for VirInterpreterBackendCacheWrapp fn try_from(value: SurchargeDecisionManagerRecord) -> Result { let cached_alogorith = backend::VirInterpreterBackend::with_program(value.algorithm) - .into_report() .change_context(ConfigError::DslBackendInitError) .attach_printable("Error initializing DSL interpreter backend")?; let merchant_surcharge_configs = value.merchant_surcharge_configs; @@ -127,7 +126,6 @@ pub async fn perform_surcharge_decision_management_for_payment_method_list( .await?; let cached_algo = CONF_CACHE .retrieve(&key) - .into_report() .change_context(ConfigError::CacheMiss) .attach_printable( "Unable to retrieve cached routing algorithm even after refresh", @@ -182,7 +180,6 @@ pub async fn perform_surcharge_decision_management_for_payment_method_list( &surcharge_details, payment_attempt, )) - .into_report() .change_context(ConfigError::DslExecutionError) .attach_printable("Error while constructing Surcharge response type") }) @@ -208,7 +205,6 @@ pub async fn perform_surcharge_decision_management_for_payment_method_list( &surcharge_details, payment_attempt, )) - .into_report() .change_context(ConfigError::DslExecutionError) .attach_printable("Error while constructing Surcharge response type") }) @@ -247,7 +243,6 @@ where .await?; let cached_algo = CONF_CACHE .retrieve(&key) - .into_report() .change_context(ConfigError::CacheMiss) .attach_printable( "Unable to retrieve cached routing algorithm even after refresh", @@ -306,7 +301,6 @@ pub async fn perform_surcharge_decision_management_for_saved_cards( .await?; let cached_algo = CONF_CACHE .retrieve(&key) - .into_report() .change_context(ConfigError::CacheMiss) .attach_printable( "Unable to retrieve cached routing algorithm even after refresh", @@ -345,7 +339,6 @@ pub async fn perform_surcharge_decision_management_for_saved_cards( customer_payment_method.surcharge_details = surcharge_details .map(|surcharge_details| { SurchargeDetailsResponse::foreign_try_from((&surcharge_details, payment_attempt)) - .into_report() .change_context(ConfigError::DslParsingError) }) .transpose()?; @@ -402,12 +395,10 @@ pub async fn ensure_algorithm_cached( let key = format!("surcharge_dsl_{merchant_id}"); let present = CONF_CACHE .present(&key) - .into_report() .change_context(ConfigError::DslCachePoisoned) .attach_printable("Error checking presence of DSL")?; let expired = CONF_CACHE .expired(&key, timestamp) - .into_report() .change_context(ConfigError::DslCachePoisoned) .attach_printable("Error checking presence of DSL")?; @@ -437,7 +428,6 @@ pub async fn refresh_surcharge_algorithm_cache( let value_to_cache = VirInterpreterBackendCacheWrapper::try_from(record)?; CONF_CACHE .save(key, value_to_cache, timestamp) - .into_report() .change_context(ConfigError::DslCachePoisoned) .attach_printable("Error saving DSL to cache")?; Ok(()) @@ -450,7 +440,6 @@ pub fn execute_dsl_and_get_conditional_config( let routing_output = interpreter .execute(backend_input) .map(|out| out.connector_selection) - .into_report() .change_context(ConfigError::DslExecutionError)?; Ok(routing_output) } diff --git a/crates/router/src/core/payment_methods/vault.rs b/crates/router/src/core/payment_methods/vault.rs index af9f94a0bdf..aeb1ea102be 100644 --- a/crates/router/src/core/payment_methods/vault.rs +++ b/crates/router/src/core/payment_methods/vault.rs @@ -3,7 +3,7 @@ use common_utils::{ ext_traits::{BytesExt, Encode}, generate_id_with_default_len, }; -use error_stack::{report, IntoReport, ResultExt}; +use error_stack::{report, ResultExt}; use masking::PeekInterface; use router_env::{instrument, tracing}; use scheduler::{types::process_data, utils as process_tracker_utils}; @@ -90,10 +90,7 @@ impl Vaultable for api::Card { .attach_printable("Could not deserialize into card value2")?; let card = Self { - card_number: value1 - .card_number - .try_into() - .into_report() + card_number: cards::CardNumber::try_from(value1.card_number) .change_context(errors::VaultError::ResponseDeserializationFailed) .attach_printable("Invalid card number format from the mock locker")?, card_exp_month: value1.exp_month.into(), @@ -276,7 +273,6 @@ impl Vaultable for api::PaymentMethodData { VaultPaymentMethod::BankRedirect(bank_redirect.get_value1(customer_id)?) } _ => Err(errors::VaultError::PaymentMethodNotSupported) - .into_report() .attach_printable("Payment method not supported")?, }; @@ -297,7 +293,6 @@ impl Vaultable for api::PaymentMethodData { VaultPaymentMethod::BankRedirect(bank_redirect.get_value2(customer_id)?) } _ => Err(errors::VaultError::PaymentMethodNotSupported) - .into_report() .attach_printable("Payment method not supported")?, }; @@ -348,7 +343,6 @@ impl Vaultable for api::PaymentMethodData { } _ => Err(errors::VaultError::PaymentMethodNotSupported) - .into_report() .attach_printable("Payment method not supported"), } } @@ -678,7 +672,6 @@ impl Vaultable for api::PayoutMethodData { Ok((Self::Wallet(wallet), supp_data)) } _ => Err(errors::VaultError::PayoutMethodNotSupported) - .into_report() .attach_printable("Payout method not supported"), } } @@ -963,16 +956,13 @@ pub async fn delete_tokenized_data(state: &routes::AppState, lookup_key: &str) - Ok(redis_interface::DelReply::KeyDeleted) => Ok(()), Ok(redis_interface::DelReply::KeyNotDeleted) => { Err(errors::ApiErrorResponse::InternalServerError) - .into_report() .attach_printable("Token invalid or expired") } Err(err) => { metrics::TEMP_LOCKER_FAILURES.add(&metrics::CONTEXT, 1, &[]); - Err(errors::ApiErrorResponse::InternalServerError) - .into_report() - .attach_printable_lazy(|| { - format!("Failed to delete from redis locker: {err:?}") - }) + Err(errors::ApiErrorResponse::InternalServerError).attach_printable_lazy(|| { + format!("Failed to delete from redis locker: {err:?}") + }) } } }; @@ -1009,7 +999,6 @@ pub async fn add_delete_tokenized_data_task( let schedule_time = get_delete_tokenize_schedule_time(db, &pm, 0) .await .ok_or(errors::ApiErrorResponse::InternalServerError) - .into_report() .attach_printable("Failed to obtain initial process tracker schedule time")?; let process_tracker_entry = storage::ProcessTrackerNew::new( @@ -1041,7 +1030,6 @@ pub async fn start_tokenize_data_workflow( let delete_tokenize_data = serde_json::from_value::( tokenize_tracker.tracking_data.clone(), ) - .into_report() .change_context(errors::ApiErrorResponse::InternalServerError) .attach_printable_lazy(|| { format!( diff --git a/crates/router/src/core/payments.rs b/crates/router/src/core/payments.rs index e11a77496af..b996677f7e6 100644 --- a/crates/router/src/core/payments.rs +++ b/crates/router/src/core/payments.rs @@ -21,7 +21,7 @@ use api_models::{ use common_utils::{ext_traits::AsyncExt, pii, types::Surcharge}; use data_models::mandates::{CustomerAcceptance, MandateData}; use diesel_models::{ephemeral_key, fraud_check::FraudCheck}; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use futures::future::join_all; use helpers::ApplePayData; use masking::Secret; @@ -254,7 +254,6 @@ where 0, ) .await - .into_report() .change_context(errors::ApiErrorResponse::InternalServerError) .attach_printable("Failed while getting process schedule time")? } else { @@ -310,7 +309,6 @@ where 0, ) .await - .into_report() .change_context(errors::ApiErrorResponse::InternalServerError) .attach_printable("Failed while getting process schedule time")? } else { @@ -420,7 +418,6 @@ where .ok_or(errors::ApiErrorResponse::MissingRequiredField { field_name: "frm_configs", }) - .into_report() .attach_printable("Frm configs label not found")?, &customer, key_store.clone(), @@ -615,7 +612,6 @@ pub fn get_connector_data( connectors .next() .ok_or(errors::ApiErrorResponse::InternalServerError) - .into_report() .attach_printable("Connector not found in connectors iterator") } @@ -838,7 +834,6 @@ pub trait PaymentRedirectFlow: Sync { services::ApplicationResponse::Json(response) => Ok(response), services::ApplicationResponse::JsonWithHeaders((response, _)) => Ok(response), _ => Err(errors::ApiErrorResponse::InternalServerError) - .into_report() .attach_printable("Failed to get the response in json"), }?; @@ -933,7 +928,7 @@ impl PaymentRedirectFlow for PaymentRedirectCom api_models::payments::NextActionData::ThreeDsInvoke{..} => None, }) .ok_or(errors::ApiErrorResponse::InternalServerError) - .into_report() + .attach_printable( "did not receive redirect to url when status is requires customer action", )?; @@ -954,7 +949,7 @@ impl PaymentRedirectFlow for PaymentRedirectCom payments_response, connector, ), - _ => Err(errors::ApiErrorResponse::InternalServerError).into_report().attach_printable_lazy(|| format!("Could not proceed with payment as payment status {} cannot be handled during redirection",payments_response.status))? + _ => Err(errors::ApiErrorResponse::InternalServerError).attach_printable_lazy(|| format!("Could not proceed with payment as payment status {} cannot be handled during redirection",payments_response.status))? }?; Ok(services::ApplicationResponse::JsonForRedirection( redirection_response, @@ -2576,8 +2571,7 @@ pub async fn add_process_sync_task( tracking_data, schedule_time, ) - .map_err(errors::StorageError::from) - .into_report()?; + .map_err(errors::StorageError::from)?; db.insert_process(process_tracker_entry).await?; Ok(()) @@ -3065,7 +3059,6 @@ pub fn decide_multiplex_connector_for_normal_or_recurring_payment( let first_choice = connectors .first() .ok_or(errors::ApiErrorResponse::IncorrectPaymentMethodConfiguration) - .into_report() .attach_printable("no eligible connector found for payment")? .clone(); @@ -3274,7 +3267,6 @@ where let first_connector_choice = connectors .first() .ok_or(errors::ApiErrorResponse::IncorrectPaymentMethodConfiguration) - .into_report() .attach_printable("Empty connector list returned")? .clone(); @@ -3409,7 +3401,6 @@ pub async fn payment_external_authentication( .authentication_connector .clone() .ok_or(errors::ApiErrorResponse::InternalServerError) - .into_report() .attach_printable("authentication_connector not found in payment_attempt")?; let merchant_connector_account = helpers::get_merchant_connector_account( &state, @@ -3428,7 +3419,6 @@ pub async fn payment_external_authentication( .authentication_id .clone() .ok_or(errors::ApiErrorResponse::InternalServerError) - .into_report() .attach_printable("missing authentication_id in payment_attempt")?, ) .await @@ -3442,7 +3432,6 @@ pub async fn payment_external_authentication( ) .await? .ok_or(errors::ApiErrorResponse::InternalServerError) - .into_report() .attach_printable("missing payment_method_details")?; let browser_info: Option = payment_attempt .browser_info @@ -3456,7 +3445,6 @@ pub async fn payment_external_authentication( .connector .as_ref() .ok_or(errors::ApiErrorResponse::InternalServerError) - .into_report() .attach_printable("missing connector in payment_attempt")?; let return_url = Some(helpers::create_authorize_url( &state.conf.server.base_url, diff --git a/crates/router/src/core/payments/access_token.rs b/crates/router/src/core/payments/access_token.rs index b95c294466d..47f6b7e2ae4 100644 --- a/crates/router/src/core/payments/access_token.rs +++ b/crates/router/src/core/payments/access_token.rs @@ -1,7 +1,7 @@ use std::fmt::Debug; use common_utils::ext_traits::AsyncExt; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use crate::{ consts, @@ -77,7 +77,6 @@ pub async fn add_access_token< let refresh_token_request_data = types::AccessTokenRequestData::try_from( router_data.connector_auth_type.clone(), ) - .into_report() .attach_printable( "Could not create access token request, invalid connector account credentials", )?; diff --git a/crates/router/src/core/payments/conditional_configs.rs b/crates/router/src/core/payments/conditional_configs.rs index bf1f43e2b0f..5dc78d42e5e 100644 --- a/crates/router/src/core/payments/conditional_configs.rs +++ b/crates/router/src/core/payments/conditional_configs.rs @@ -5,7 +5,7 @@ use api_models::{ routing, }; use common_utils::{ext_traits::StringExt, static_cache::StaticCache}; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use euclid::backend::{self, inputs as dsl_inputs, EuclidBackend}; use router_env::{instrument, tracing}; @@ -41,7 +41,6 @@ pub async fn perform_decision_management( .await?; let cached_algo = CONF_CACHE .retrieve(&key) - .into_report() .change_context(ConfigError::CacheMiss) .attach_printable("Unable to retrieve cached routing algorithm even after refresh")?; let backend_input = @@ -60,12 +59,10 @@ pub async fn ensure_algorithm_cached( let key = format!("dsl_{merchant_id}"); let present = CONF_CACHE .present(&key) - .into_report() .change_context(ConfigError::DslCachePoisoned) .attach_printable("Error checking presece of DSL")?; let expired = CONF_CACHE .expired(&key, timestamp) - .into_report() .change_context(ConfigError::DslCachePoisoned) .attach_printable("Error checking presence of DSL")?; if !present || expired { @@ -94,12 +91,10 @@ pub async fn refresh_routing_cache( .attach_printable("Error parsing routing algorithm from configs")?; let interpreter: backend::VirInterpreterBackend = backend::VirInterpreterBackend::with_program(rec.program) - .into_report() .change_context(ConfigError::DslBackendInitError) .attach_printable("Error initializing DSL interpreter backend")?; CONF_CACHE .save(key, interpreter, timestamp) - .into_report() .change_context(ConfigError::DslCachePoisoned) .attach_printable("Error saving DSL to cache")?; Ok(()) @@ -112,7 +107,6 @@ pub async fn execute_dsl_and_get_conditional_config( let routing_output = interpreter .execute(backend_input) .map(|out| out.connector_selection) - .into_report() .change_context(ConfigError::DslExecutionError)?; Ok(routing_output) } diff --git a/crates/router/src/core/payments/flows/session_flow.rs b/crates/router/src/core/payments/flows/session_flow.rs index 4321c0c0913..349c76cd23a 100644 --- a/crates/router/src/core/payments/flows/session_flow.rs +++ b/crates/router/src/core/payments/flows/session_flow.rs @@ -1,7 +1,7 @@ use api_models::payments as payment_types; use async_trait::async_trait; use common_utils::{ext_traits::ByteSliceExt, request::RequestContent}; -use error_stack::{IntoReport, Report, ResultExt}; +use error_stack::{Report, ResultExt}; use masking::ExposeInterface; use super::{ConstructFlowSpecificData, Feature}; @@ -337,7 +337,6 @@ fn get_apple_pay_amount_info( amount: session_data .currency .to_currency_base_unit(session_data.amount) - .into_report() .change_context(errors::ApiErrorResponse::PreconditionFailed { message: "Failed to convert currency to base unit".to_string(), })?, @@ -445,7 +444,6 @@ fn create_gpay_session_token( .request .currency .to_currency_base_unit(router_data.request.amount) - .into_report() .attach_printable( "Cannot convert given amount to base currency denomination".to_string(), ) diff --git a/crates/router/src/core/payments/flows/setup_mandate_flow.rs b/crates/router/src/core/payments/flows/setup_mandate_flow.rs index 189a8a0a3ed..0d663df2980 100644 --- a/crates/router/src/core/payments/flows/setup_mandate_flow.rs +++ b/crates/router/src/core/payments/flows/setup_mandate_flow.rs @@ -1,6 +1,6 @@ use api_models::enums::{PaymentMethod, PaymentMethodType}; use async_trait::async_trait; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use super::{ConstructFlowSpecificData, Feature}; use crate::{ @@ -397,7 +397,6 @@ impl types::SetupMandateRouterData { .await } Ok(_) => Err(errors::ApiErrorResponse::InternalServerError) - .into_report() .attach_printable("Unexpected response received")?, Err(_) => Ok(resp), } @@ -407,8 +406,8 @@ impl types::SetupMandateRouterData { "Update Mandate flow not implemented for the connector {:?}", connector.connector_name ), - }) - .into_report() + } + .into()) } } } diff --git a/crates/router/src/core/payments/helpers.rs b/crates/router/src/core/payments/helpers.rs index e9cefbf8aed..0f80b6a52ea 100644 --- a/crates/router/src/core/payments/helpers.rs +++ b/crates/router/src/core/payments/helpers.rs @@ -15,7 +15,7 @@ use data_models::{ }; use diesel_models::enums; // TODO : Evaluate all the helper functions () -use error_stack::{report, IntoReport, ResultExt}; +use error_stack::{report, ResultExt}; use josekit::jwe; use masking::{ExposeInterface, PeekInterface}; use openssl::{ @@ -69,24 +69,19 @@ pub fn create_identity_from_certificate_and_key( ) -> Result> { let decoded_certificate = BASE64_ENGINE .decode(encoded_certificate) - .into_report() .change_context(errors::ApiClientError::CertificateDecodeFailed)?; let decoded_certificate_key = BASE64_ENGINE .decode(encoded_certificate_key) - .into_report() .change_context(errors::ApiClientError::CertificateDecodeFailed)?; let certificate = String::from_utf8(decoded_certificate) - .into_report() .change_context(errors::ApiClientError::CertificateDecodeFailed)?; let certificate_key = String::from_utf8(decoded_certificate_key) - .into_report() .change_context(errors::ApiClientError::CertificateDecodeFailed)?; reqwest::Identity::from_pkcs8_pem(certificate.as_bytes(), certificate_key.as_bytes()) - .into_report() .change_context(errors::ApiClientError::CertificateDecodeFailed) } @@ -122,74 +117,76 @@ pub async fn create_or_update_address_for_payment_by_request( Some(id) => match req_address { Some(address) => { let address_update = async { - Ok(storage::AddressUpdate::Update { - city: address - .address - .as_ref() - .and_then(|value| value.city.clone()), - country: address.address.as_ref().and_then(|value| value.country), - line1: address - .address - .as_ref() - .and_then(|value| value.line1.clone()) - .async_lift(|inner| types::encrypt_optional(inner, key)) - .await?, - line2: address - .address - .as_ref() - .and_then(|value| value.line2.clone()) - .async_lift(|inner| types::encrypt_optional(inner, key)) - .await?, - line3: address - .address - .as_ref() - .and_then(|value| value.line3.clone()) - .async_lift(|inner| types::encrypt_optional(inner, key)) - .await?, - state: address - .address - .as_ref() - .and_then(|value| value.state.clone()) - .async_lift(|inner| types::encrypt_optional(inner, key)) - .await?, - zip: address - .address - .as_ref() - .and_then(|value| value.zip.clone()) - .async_lift(|inner| types::encrypt_optional(inner, key)) - .await?, - first_name: address - .address - .as_ref() - .and_then(|value| value.first_name.clone()) - .async_lift(|inner| types::encrypt_optional(inner, key)) - .await?, - last_name: address - .address - .as_ref() - .and_then(|value| value.last_name.clone()) - .async_lift(|inner| types::encrypt_optional(inner, key)) - .await?, - phone_number: address - .phone - .as_ref() - .and_then(|value| value.number.clone()) - .async_lift(|inner| types::encrypt_optional(inner, key)) - .await?, - country_code: address - .phone - .as_ref() - .and_then(|value| value.country_code.clone()), - updated_by: storage_scheme.to_string(), - email: address - .email - .as_ref() - .cloned() - .async_lift(|inner| { - types::encrypt_optional(inner.map(|inner| inner.expose()), key) - }) - .await?, - }) + Ok::<_, error_stack::Report>( + storage::AddressUpdate::Update { + city: address + .address + .as_ref() + .and_then(|value| value.city.clone()), + country: address.address.as_ref().and_then(|value| value.country), + line1: address + .address + .as_ref() + .and_then(|value| value.line1.clone()) + .async_lift(|inner| types::encrypt_optional(inner, key)) + .await?, + line2: address + .address + .as_ref() + .and_then(|value| value.line2.clone()) + .async_lift(|inner| types::encrypt_optional(inner, key)) + .await?, + line3: address + .address + .as_ref() + .and_then(|value| value.line3.clone()) + .async_lift(|inner| types::encrypt_optional(inner, key)) + .await?, + state: address + .address + .as_ref() + .and_then(|value| value.state.clone()) + .async_lift(|inner| types::encrypt_optional(inner, key)) + .await?, + zip: address + .address + .as_ref() + .and_then(|value| value.zip.clone()) + .async_lift(|inner| types::encrypt_optional(inner, key)) + .await?, + first_name: address + .address + .as_ref() + .and_then(|value| value.first_name.clone()) + .async_lift(|inner| types::encrypt_optional(inner, key)) + .await?, + last_name: address + .address + .as_ref() + .and_then(|value| value.last_name.clone()) + .async_lift(|inner| types::encrypt_optional(inner, key)) + .await?, + phone_number: address + .phone + .as_ref() + .and_then(|value| value.number.clone()) + .async_lift(|inner| types::encrypt_optional(inner, key)) + .await?, + country_code: address + .phone + .as_ref() + .and_then(|value| value.country_code.clone()), + updated_by: storage_scheme.to_string(), + email: address + .email + .as_ref() + .cloned() + .async_lift(|inner| { + types::encrypt_optional(inner.map(|inner| inner.expose()), key) + }) + .await?, + }, + ) } .await .change_context(errors::ApiErrorResponse::InternalServerError) @@ -769,11 +766,11 @@ pub fn validate_card_data( message: "Invalid card_cvc length".to_string() }))? } - let card_cvc = cvc.parse::().into_report().change_context( - errors::ApiErrorResponse::InvalidDataValue { - field_name: "card_cvc", - }, - )?; + let card_cvc = + cvc.parse::() + .change_context(errors::ApiErrorResponse::InvalidDataValue { + field_name: "card_cvc", + })?; ::cards::CardSecurityCode::try_from(card_cvc).change_context( errors::ApiErrorResponse::PreconditionFailed { message: "Invalid Card CVC".to_string(), @@ -785,7 +782,6 @@ pub fn validate_card_data( .peek() .to_string() .parse::() - .into_report() .change_context(errors::ApiErrorResponse::InvalidDataValue { field_name: "card_exp_month", })?; @@ -798,11 +794,12 @@ pub fn validate_card_data( if year_str.len() == 2 { year_str = format!("20{}", year_str); } - let exp_year = year_str.parse::().into_report().change_context( - errors::ApiErrorResponse::InvalidDataValue { - field_name: "card_exp_year", - }, - )?; + let exp_year = + year_str + .parse::() + .change_context(errors::ApiErrorResponse::InvalidDataValue { + field_name: "card_exp_year", + })?; let year = ::cards::CardExpirationYear::try_from(exp_year).change_context( errors::ApiErrorResponse::PreconditionFailed { message: "Invalid Expiry Year".to_string(), @@ -941,8 +938,8 @@ pub fn validate_customer_id_mandatory_cases( match (has_setup_future_usage, customer_id) { (true, None) => Err(errors::ApiErrorResponse::PreconditionFailed { message: "customer_id is mandatory when setup_future_usage is given".to_string(), - }) - .into_report(), + } + .into()), _ => Ok(()), } } @@ -1148,7 +1145,6 @@ where ); super::reset_process_sync_task(&*state.store, payment_attempt, stime) .await - .into_report() .change_context(errors::ApiErrorResponse::InternalServerError) .attach_printable("Failed while updating task in process tracker") } @@ -1424,34 +1420,36 @@ pub async fn create_customer_if_not_exist<'a, F: Clone, R, Ctx>( { let key = key_store.key.get_inner().peek(); let customer_update = async { - Ok(Update { - name: request_customer_details - .name - .async_lift(|inner| types::encrypt_optional(inner, key)) - .await?, - email: request_customer_details - .email - .clone() - .async_lift(|inner| { - types::encrypt_optional( - inner.map(|inner| inner.expose()), - key, - ) - }) - .await?, - phone: Box::new( - request_customer_details - .phone - .clone() + Ok::<_, error_stack::Report>( + Update { + name: request_customer_details + .name .async_lift(|inner| types::encrypt_optional(inner, key)) .await?, - ), - phone_country_code: request_customer_details.phone_country_code, - description: None, - connector_customer: None, - metadata: None, - address_id: None, - }) + email: request_customer_details + .email + .clone() + .async_lift(|inner| { + types::encrypt_optional( + inner.map(|inner| inner.expose()), + key, + ) + }) + .await?, + phone: Box::new( + request_customer_details + .phone + .clone() + .async_lift(|inner| types::encrypt_optional(inner, key)) + .await?, + ), + phone_country_code: request_customer_details.phone_country_code, + description: None, + connector_customer: None, + metadata: None, + address_id: None, + }, + ) } .await .change_context(errors::StorageError::SerializationFailed) @@ -1471,35 +1469,42 @@ pub async fn create_customer_if_not_exist<'a, F: Clone, R, Ctx>( None => { let new_customer = async { let key = key_store.key.get_inner().peek(); - Ok(domain::Customer { - customer_id: customer_id.to_string(), - merchant_id: merchant_id.to_string(), - name: request_customer_details - .name - .async_lift(|inner| types::encrypt_optional(inner, key)) - .await?, - email: request_customer_details - .email - .clone() - .async_lift(|inner| { - types::encrypt_optional(inner.map(|inner| inner.expose()), key) - }) - .await?, - phone: request_customer_details - .phone - .clone() - .async_lift(|inner| types::encrypt_optional(inner, key)) - .await?, - phone_country_code: request_customer_details.phone_country_code.clone(), - description: None, - created_at: common_utils::date_time::now(), - id: None, - metadata: None, - modified_at: common_utils::date_time::now(), - connector_customer: None, - address_id: None, - default_payment_method_id: None, - }) + Ok::<_, error_stack::Report>( + domain::Customer { + customer_id: customer_id.to_string(), + merchant_id: merchant_id.to_string(), + name: request_customer_details + .name + .async_lift(|inner| types::encrypt_optional(inner, key)) + .await?, + email: request_customer_details + .email + .clone() + .async_lift(|inner| { + types::encrypt_optional( + inner.map(|inner| inner.expose()), + key, + ) + }) + .await?, + phone: request_customer_details + .phone + .clone() + .async_lift(|inner| types::encrypt_optional(inner, key)) + .await?, + phone_country_code: request_customer_details + .phone_country_code + .clone(), + description: None, + created_at: common_utils::date_time::now(), + id: None, + metadata: None, + modified_at: common_utils::date_time::now(), + connector_customer: None, + address_id: None, + default_payment_method_id: None, + }, + ) } .await .change_context(errors::StorageError::SerializationFailed) @@ -1633,7 +1638,6 @@ pub async fn retrieve_payment_method_with_temporary_token( } Some(_) => Err(errors::ApiErrorResponse::InternalServerError) - .into_report() .attach_printable("Payment method received from locker is unsupported by locker")?, None => None, @@ -2326,7 +2330,6 @@ pub fn make_merchant_url_with_response( let payment_client_secret = client_secret .ok_or(errors::ApiErrorResponse::InternalServerError) - .into_report() .attach_printable("Expected client secret to be `Some`")?; let merchant_url_with_response = if business_profile.redirect_to_merchant_with_http_post { @@ -2344,7 +2347,6 @@ pub fn make_merchant_url_with_response( ), ], ) - .into_report() .change_context(errors::ApiErrorResponse::InternalServerError) .attach_printable("Unable to parse the url with param")? } else { @@ -2364,7 +2366,6 @@ pub fn make_merchant_url_with_response( ), ], ) - .into_report() .change_context(errors::ApiErrorResponse::InternalServerError) .attach_printable("Unable to parse the url with param")? }; @@ -2426,7 +2427,6 @@ pub fn make_url_with_signature( business_profile: &diesel_models::business_profile::BusinessProfile, ) -> RouterResult { let mut url = url::Url::parse(redirect_url) - .into_report() .change_context(errors::ApiErrorResponse::InternalServerError) .attach_printable("Unable to parse the url")?; @@ -2754,8 +2754,7 @@ pub fn get_business_details( pub(crate) fn get_payment_id_from_client_secret(cs: &str) -> RouterResult { let (payment_id, _) = cs .rsplit_once("_secret_") - .ok_or(errors::ApiErrorResponse::ClientSecretInvalid) - .into_report()?; + .ok_or(errors::ApiErrorResponse::ClientSecretInvalid)?; Ok(payment_id.to_string()) } @@ -3203,7 +3202,6 @@ pub fn get_attempt_type( )], ); Err(errors::ApiErrorResponse::InternalServerError) - .into_report() .attach_printable("Payment Attempt unexpected state") } @@ -3700,7 +3698,6 @@ impl ApplePayData { let symmetric_key = self.symmetric_key(&merchant_id, &shared_secret)?; let decrypted = self.decrypt_ciphertext(&symmetric_key)?; let parsed_decrypted: serde_json::Value = serde_json::from_str(&decrypted) - .into_report() .change_context(errors::ApplePayDecryptionError::DecryptionFailed)?; Ok(parsed_decrypted) } @@ -3719,12 +3716,10 @@ impl ApplePayData { let base64_decode_cert_data = BASE64_ENGINE .decode(cert_data) - .into_report() .change_context(errors::ApplePayDecryptionError::Base64DecodingFailed)?; // Parsing the certificate using x509-parser let (_, certificate) = parse_x509_certificate(&base64_decode_cert_data) - .into_report() .change_context(errors::ApplePayDecryptionError::CertificateParsingFailed) .attach_printable("Error parsing apple pay PPC")?; @@ -3747,7 +3742,6 @@ impl ApplePayData { merchant_id }) .ok_or(errors::ApplePayDecryptionError::MissingMerchantId) - .into_report() .attach_printable("Unable to find merchant ID extension in the certificate")?; Ok(apple_pay_m_id) @@ -3759,11 +3753,9 @@ impl ApplePayData { ) -> CustomResult, errors::ApplePayDecryptionError> { let public_ec_bytes = BASE64_ENGINE .decode(self.header.ephemeral_public_key.peek().as_bytes()) - .into_report() .change_context(errors::ApplePayDecryptionError::Base64DecodingFailed)?; let public_key = PKey::public_key_from_der(&public_ec_bytes) - .into_report() .change_context(errors::ApplePayDecryptionError::KeyDeserializationFailed) .attach_printable("Failed to deserialize the public key")?; @@ -3777,26 +3769,22 @@ impl ApplePayData { // Create PKey objects from EcKey let private_key = PKey::private_key_from_pem(decrypted_apple_pay_ppc_key.as_bytes()) - .into_report() .change_context(errors::ApplePayDecryptionError::KeyDeserializationFailed) .attach_printable("Failed to deserialize the private key")?; // Create the Deriver object and set the peer public key let mut deriver = Deriver::new(&private_key) - .into_report() .change_context(errors::ApplePayDecryptionError::DerivingSharedSecretKeyFailed) .attach_printable("Failed to create a deriver for the private key")?; deriver .set_peer(&public_key) - .into_report() .change_context(errors::ApplePayDecryptionError::DerivingSharedSecretKeyFailed) .attach_printable("Failed to set the peer key for the secret derivation")?; // Compute the shared secret let shared_secret = deriver .derive_to_vec() - .into_report() .change_context(errors::ApplePayDecryptionError::DerivingSharedSecretKeyFailed) .attach_printable("Final key derivation failed")?; Ok(shared_secret) @@ -3809,7 +3797,6 @@ impl ApplePayData { ) -> CustomResult, errors::ApplePayDecryptionError> { let kdf_algorithm = b"\x0did-aes256-GCM"; let kdf_party_v = hex::decode(merchant_id) - .into_report() .change_context(errors::ApplePayDecryptionError::Base64DecodingFailed)?; let kdf_party_u = b"Apple"; let kdf_info = [&kdf_algorithm[..], kdf_party_u, &kdf_party_v[..]].concat(); @@ -3829,7 +3816,6 @@ impl ApplePayData { ) -> CustomResult { let data = BASE64_ENGINE .decode(self.data.peek().as_bytes()) - .into_report() .change_context(errors::ApplePayDecryptionError::Base64DecodingFailed)?; let iv = [0u8; 16]; //Initialization vector IV is typically used in AES-GCM (Galois/Counter Mode) encryption for randomizing the encryption process. let ciphertext = data @@ -3840,10 +3826,8 @@ impl ApplePayData { .ok_or(errors::ApplePayDecryptionError::DecryptionFailed)?; let cipher = Cipher::aes_256_gcm(); let decrypted_data = decrypt_aead(cipher, symmetric_key, Some(&iv), &[], ciphertext, tag) - .into_report() .change_context(errors::ApplePayDecryptionError::DecryptionFailed)?; let decrypted = String::from_utf8(decrypted_data) - .into_report() .change_context(errors::ApplePayDecryptionError::DecryptionFailed)?; Ok(decrypted) @@ -4128,7 +4112,6 @@ pub async fn get_payment_method_details_from_payment_token( }; let token = hyperswitch_token .ok_or(errors::ApiErrorResponse::InternalServerError) - .into_report() .attach_printable("missing hyperswitch_token")?; match token { storage::PaymentTokenData::TemporaryGeneric(generic_token) => { diff --git a/crates/router/src/core/payments/operations/payment_approve.rs b/crates/router/src/core/payments/operations/payment_approve.rs index a2132bed8c1..e25ef7ed4a4 100644 --- a/crates/router/src/core/payments/operations/payment_approve.rs +++ b/crates/router/src/core/payments/operations/payment_approve.rs @@ -2,7 +2,7 @@ use std::marker::PhantomData; use api_models::enums::FrmSuggestion; use async_trait::async_trait; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use router_derive::PaymentOperation; use router_env::{instrument, tracing}; @@ -255,10 +255,10 @@ impl Box::new(self), operations::ValidateResult { merchant_id: &merchant_account.merchant_id, - payment_id: api::PaymentIdType::PaymentIntentId( - crate::core::utils::validate_id(request.payment_id.clone(), "payment_id") - .into_report()?, - ), + payment_id: api::PaymentIdType::PaymentIntentId(crate::core::utils::validate_id( + request.payment_id.clone(), + "payment_id", + )?), mandate_type: None, storage_scheme: merchant_account.storage_scheme, requeue: false, diff --git a/crates/router/src/core/payments/operations/payment_complete_authorize.rs b/crates/router/src/core/payments/operations/payment_complete_authorize.rs index b788ebc95f7..9d0971982a6 100644 --- a/crates/router/src/core/payments/operations/payment_complete_authorize.rs +++ b/crates/router/src/core/payments/operations/payment_complete_authorize.rs @@ -2,7 +2,7 @@ use std::marker::PhantomData; use api_models::enums::FrmSuggestion; use async_trait::async_trait; -use error_stack::{report, IntoReport, ResultExt}; +use error_stack::{report, ResultExt}; use router_derive::PaymentOperation; use router_env::{instrument, tracing}; @@ -467,9 +467,7 @@ impl ValidateRequest Domain ValidateRequest PostUpdateTracker, types::PaymentsIncrementalAu } } _ => Err(errors::ApiErrorResponse::InternalServerError) - .into_report() .attach_printable("unexpected response in incremental_authorization flow")?, }; //payment_attempt update @@ -178,7 +177,6 @@ impl PostUpdateTracker, types::PaymentsIncrementalAu connector_authorization_id: connector_authorization_id.clone(), }), Ok(_) => Err(errors::ApiErrorResponse::InternalServerError) - .into_report() .attach_printable("unexpected response in incremental_authorization flow"), }?; let authorization_id = incremental_authorization_details diff --git a/crates/router/src/core/payments/operations/payment_update.rs b/crates/router/src/core/payments/operations/payment_update.rs index 684f7c4b698..a6a41732f1b 100644 --- a/crates/router/src/core/payments/operations/payment_update.rs +++ b/crates/router/src/core/payments/operations/payment_update.rs @@ -5,7 +5,7 @@ use api_models::{ }; use async_trait::async_trait; use common_utils::ext_traits::{AsyncExt, Encode, ValueExt}; -use error_stack::{report, IntoReport, ResultExt}; +use error_stack::{report, ResultExt}; use router_derive::PaymentOperation; use router_env::{instrument, tracing}; @@ -760,9 +760,7 @@ impl ValidateRequest }); } None => Err(errors::ApiErrorResponse::InternalServerError) - .into_report() .attach_printable("missing incremental_authorization_details in payment_data")?, } Ok((Box::new(self), payment_data)) diff --git a/crates/router/src/core/payments/retry.rs b/crates/router/src/core/payments/retry.rs index 2c0183922b1..09400bb750b 100644 --- a/crates/router/src/core/payments/retry.rs +++ b/crates/router/src/core/payments/retry.rs @@ -2,7 +2,7 @@ use std::{str::FromStr, vec::IntoIter}; use common_utils::ext_traits::Encode; use diesel_models::enums as storage_enums; -use error_stack::{IntoReport, ResultExt}; +use error_stack::{report, ResultExt}; use router_env::{ logger, tracing::{self, instrument}, @@ -142,12 +142,11 @@ where retries = retries.map(|i| i - 1); } api_models::gsm::GsmDecision::Requeue => { - Err(errors::ApiErrorResponse::NotImplemented { + Err(report!(errors::ApiErrorResponse::NotImplemented { message: errors::api_error_response::NotImplementedMessage::Reason( "Requeue not implemented".to_string(), ), - }) - .into_report()? + }))? } api_models::gsm::GsmDecision::DoDefault => break, } @@ -170,7 +169,6 @@ pub async fn is_step_up_enabled_for_merchant_connector( .change_context(errors::ApiErrorResponse::InternalServerError) .and_then(|step_up_config| { serde_json::from_str::>(&step_up_config.config) - .into_report() .change_context(errors::ApiErrorResponse::InternalServerError) .attach_printable("Step-up config parsing failed") }) @@ -200,7 +198,6 @@ pub async fn get_retries( retries_config .config .parse::() - .into_report() .change_context(errors::ApiErrorResponse::InternalServerError) .attach_printable("Retries config parsing failed") }) @@ -236,9 +233,8 @@ pub fn get_gsm_decision( let option_gsm_decision = option_gsm .and_then(|gsm| { api_models::gsm::GsmDecision::from_str(gsm.decision.as_str()) - .into_report() .map_err(|err| { - let api_error = err.change_context(errors::ApiErrorResponse::InternalServerError) + let api_error = report!(err).change_context(errors::ApiErrorResponse::InternalServerError) .attach_printable("gsm decision parsing failed"); logger::warn!(get_gsm_decision_parse_error=?api_error, "error fetching gsm decision"); api_error @@ -259,7 +255,6 @@ fn get_flow_name() -> RouterResult { .rsplit("::") .next() .ok_or(errors::ApiErrorResponse::InternalServerError) - .into_report() .attach_printable("Flow stringify failed")? .to_string()) } diff --git a/crates/router/src/core/payments/routing.rs b/crates/router/src/core/payments/routing.rs index d8a23ce9161..e2502e2ecb6 100644 --- a/crates/router/src/core/payments/routing.rs +++ b/crates/router/src/core/payments/routing.rs @@ -14,7 +14,7 @@ use api_models::{ }; use common_utils::static_cache::StaticCache; use diesel_models::enums as storage_enums; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use euclid::{ backend::{self, inputs as dsl_inputs, EuclidBackend}, dssa::graph::{self as euclid_graph, Memoization}, @@ -310,7 +310,6 @@ pub async fn perform_static_routing_v1( .await?; let cached_algorithm: Arc = ROUTING_CACHE .retrieve(&key) - .into_report() .change_context(errors::RoutingError::CacheMiss) .attach_printable("Unable to retrieve cached routing algorithm even after refresh")?; @@ -375,13 +374,11 @@ async fn ensure_algorithm_cached_v1( let present = ROUTING_CACHE .present(&key) - .into_report() .change_context(errors::RoutingError::DslCachePoisoned) .attach_printable("Error checking presence of DSL")?; let expired = ROUTING_CACHE .expired(&key, timestamp) - .into_report() .change_context(errors::RoutingError::DslCachePoisoned) .attach_printable("Error checking expiry of DSL in cache")?; @@ -429,7 +426,6 @@ fn execute_dsl_and_get_connector_v1( let routing_output: routing_types::RoutingAlgorithm = interpreter .execute(backend_input) .map(|out| out.connector_selection.foreign_into()) - .into_report() .change_context(errors::RoutingError::DslExecutionError)?; Ok(match routing_output { @@ -439,7 +435,6 @@ fn execute_dsl_and_get_connector_v1( .change_context(errors::RoutingError::DslFinalConnectorSelectionFailed)?, _ => Err(errors::RoutingError::DslIncorrectSelectionAlgorithm) - .into_report() .attach_printable("Unsupported algorithm received as a result of static routing")?, }) } @@ -492,7 +487,6 @@ pub async fn refresh_routing_cache_v1( } routing_types::RoutingAlgorithm::Advanced(program) => { let interpreter = backend::VirInterpreterBackend::with_program(program) - .into_report() .change_context(errors::RoutingError::DslBackendInitError) .attach_printable("Error initializing DSL interpreter backend")?; @@ -502,7 +496,6 @@ pub async fn refresh_routing_cache_v1( ROUTING_CACHE .save(key, cached_algorithm, timestamp) - .into_report() .change_context(errors::RoutingError::DslCachePoisoned) .attach_printable("Error saving DSL to cache")?; @@ -515,7 +508,6 @@ pub fn perform_volume_split( ) -> RoutingResult> { let weights: Vec = splits.iter().map(|sp| sp.split).collect(); let weighted_index = distributions::WeightedIndex::new(weights) - .into_report() .change_context(errors::RoutingError::VolumeSplitFailed) .attach_printable("Error creating weighted distribution for volume split")?; @@ -534,7 +526,6 @@ pub fn perform_volume_split( splits .get(idx) .ok_or(errors::RoutingError::VolumeSplitFailed) - .into_report() .attach_printable("Volume split index lookup failed")?; // Panic Safety: We have performed a `get(idx)` operation just above which will @@ -578,13 +569,11 @@ pub async fn get_merchant_kgraph<'a>( let kgraph_present = KGRAPH_CACHE .present(&key) - .into_report() .change_context(errors::RoutingError::KgraphCacheFailure) .attach_printable("when checking kgraph presence")?; let kgraph_expired = KGRAPH_CACHE .expired(&key, merchant_last_modified) - .into_report() .change_context(errors::RoutingError::KgraphCacheFailure) .attach_printable("when checking kgraph expiry")?; @@ -603,7 +592,6 @@ pub async fn get_merchant_kgraph<'a>( let cached_kgraph = KGRAPH_CACHE .retrieve(&key) - .into_report() .change_context(errors::RoutingError::CacheMiss) .attach_printable("when retrieving kgraph")?; @@ -650,20 +638,18 @@ pub async fn refresh_kgraph_cache( profile_id, ); - let api_mcas: Vec = merchant_connector_accounts + let api_mcas = merchant_connector_accounts .into_iter() - .map(|acct| acct.try_into()) - .collect::>() + .map(admin_api::MerchantConnectorResponse::try_from) + .collect::, _>>() .change_context(errors::RoutingError::KgraphCacheRefreshFailed)?; let kgraph = mca_graph::make_mca_graph(api_mcas) - .into_report() .change_context(errors::RoutingError::KgraphCacheRefreshFailed) .attach_printable("when construction kgraph")?; KGRAPH_CACHE .save(key, kgraph, timestamp) - .into_report() .change_context(errors::RoutingError::KgraphCacheRefreshFailed) .attach_printable("when saving kgraph to cache")?; @@ -684,7 +670,6 @@ async fn perform_kgraph_filtering( let context = euclid_graph::AnalysisContext::from_dir_values( backend_input .into_context() - .into_report() .change_context(errors::RoutingError::KgraphAnalysisError)?, ); let cached_kgraph = get_merchant_kgraph( @@ -703,11 +688,9 @@ async fn perform_kgraph_filtering( let euclid_choice: ast::ConnectorChoice = choice.clone().foreign_into(); let dir_val = euclid_choice .into_dir_value() - .into_report() .change_context(errors::RoutingError::KgraphAnalysisError)?; let kgraph_eligible = cached_kgraph .check_value_validity(dir_val, &context, &mut Memoization::new()) - .into_report() .change_context(errors::RoutingError::KgraphAnalysisError)?; let filter_eligible = @@ -1031,7 +1014,6 @@ async fn perform_session_routing_for_pm_type( let cached_algorithm = ROUTING_CACHE .retrieve(&key) - .into_report() .change_context(errors::RoutingError::CacheMiss) .attach_printable("unable to retrieve cached routing algorithm")?; diff --git a/crates/router/src/core/payments/transformers.rs b/crates/router/src/core/payments/transformers.rs index e6bac7e4aa7..d686d741c88 100644 --- a/crates/router/src/core/payments/transformers.rs +++ b/crates/router/src/core/payments/transformers.rs @@ -6,7 +6,7 @@ use api_models::payouts::PayoutAttemptResponse; use common_enums::RequestIncrementalAuthorization; use common_utils::{consts::X_HS_LATENCY, fp_utils}; use diesel_models::ephemeral_key; -use error_stack::{report, IntoReport, ResultExt}; +use error_stack::{report, ResultExt}; use masking::Maskable; use router_env::{instrument, tracing}; @@ -102,7 +102,6 @@ where .multiple_api_version_supported_connectors .supported_connectors; let connector_enum = api_models::enums::Connector::from_str(connector_id) - .into_report() .change_context(errors::ConnectorError::InvalidConnectorName) .change_context(errors::ApiErrorResponse::InvalidDataValue { field_name: "connector", @@ -374,7 +373,6 @@ where .get_required_value("currency")?; let amount = currency .to_currency_base_unit(payment_attempt.amount) - .into_report() .change_context(errors::ApiErrorResponse::InvalidDataValue { field_name: "amount", })?; diff --git a/crates/router/src/core/payments/types.rs b/crates/router/src/core/payments/types.rs index ac54e1b7aa3..73825558068 100644 --- a/crates/router/src/core/payments/types.rs +++ b/crates/router/src/core/payments/types.rs @@ -9,7 +9,7 @@ use common_utils::{ }; use data_models::payments::payment_attempt::PaymentAttempt; use diesel_models::business_profile::BusinessProfile; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use redis_interface::errors::RedisError; use router_env::{instrument, tracing}; @@ -42,7 +42,6 @@ impl MultipleCaptureData { let latest_capture = captures .last() .ok_or(errors::ApiErrorResponse::InternalServerError) - .into_report() .attach_printable("Cannot create MultipleCaptureData with empty captures list")? .clone(); let multiple_capture_data = Self { @@ -105,7 +104,6 @@ impl MultipleCaptureData { } pub fn get_captures_count(&self) -> RouterResult { i16::try_from(self.all_captures.len()) - .into_report() .change_context(errors::ApiErrorResponse::InternalServerError) .attach_printable("Error while converting from usize to i16") } diff --git a/crates/router/src/core/payouts.rs b/crates/router/src/core/payouts.rs index 5f47c5251ed..566caa7acc5 100644 --- a/crates/router/src/core/payouts.rs +++ b/crates/router/src/core/payouts.rs @@ -10,7 +10,7 @@ use common_utils::{crypto::Encryptable, ext_traits::ValueExt, pii}; #[cfg(feature = "olap")] use data_models::errors::StorageError; use diesel_models::enums as storage_enums; -use error_stack::{report, IntoReport, ResultExt}; +use error_stack::{report, ResultExt}; #[cfg(feature = "olap")] use futures::future::join_all; #[cfg(feature = "olap")] @@ -58,7 +58,6 @@ pub fn get_next_connector( connectors .next() .ok_or(errors::ApiErrorResponse::InternalServerError) - .into_report() .attach_printable("Connector not found in connectors iterator") } @@ -82,7 +81,6 @@ pub async fn get_connector_choice( match connector_choice { api::ConnectorChoice::SessionMultiple(_) => { Err(errors::ApiErrorResponse::InternalServerError) - .into_report() .attach_printable("Invalid connector choice - SessionMultiple")? } @@ -539,7 +537,6 @@ pub async fn payouts_cancel_core( _ => Err(errors::ApplicationError::InvalidConfigurationValueError( "Connector not found in payout_attempt - should not reach here".to_string(), )) - .into_report() .change_context(errors::ApiErrorResponse::MissingRequiredField { field_name: "connector", }) @@ -610,7 +607,6 @@ pub async fn payouts_fulfill_core( _ => Err(errors::ApplicationError::InvalidConfigurationValueError( "Connector not found in payout_attempt - should not reach here.".to_string(), )) - .into_report() .change_context(errors::ApiErrorResponse::MissingRequiredField { field_name: "connector", }) diff --git a/crates/router/src/core/payouts/helpers.rs b/crates/router/src/core/payouts/helpers.rs index f7ee340249d..1a94186a86f 100644 --- a/crates/router/src/core/payouts/helpers.rs +++ b/crates/router/src/core/payouts/helpers.rs @@ -4,7 +4,7 @@ use common_utils::{ ext_traits::{AsyncExt, StringExt}, }; use diesel_models::encryption::Encryption; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use masking::{ExposeInterface, PeekInterface, Secret}; use router_env::logger; @@ -231,7 +231,6 @@ pub async fn save_payout_data_to_locker( let key = key_store.key.get_inner().peek(); let enc_data = async { serde_json::to_value(payout_method_data.to_owned()) - .into_report() .change_context(errors::ApiErrorResponse::InternalServerError) .attach_printable("Unable to encode payout method data") .ok() @@ -503,7 +502,6 @@ pub async fn decide_payout_connector( let first_connector_choice = connectors .first() .ok_or(errors::ApiErrorResponse::IncorrectPaymentMethodConfiguration) - .into_report() .attach_printable("Empty connector list returned")? .clone(); @@ -563,7 +561,6 @@ pub async fn decide_payout_connector( let first_connector_choice = connectors .first() .ok_or(errors::ApiErrorResponse::IncorrectPaymentMethodConfiguration) - .into_report() .attach_printable("Empty connector list returned")? .clone(); diff --git a/crates/router/src/core/payouts/retry.rs b/crates/router/src/core/payouts/retry.rs index a1a9d0b2713..fbb7ca0ba72 100644 --- a/crates/router/src/core/payouts/retry.rs +++ b/crates/router/src/core/payouts/retry.rs @@ -1,7 +1,7 @@ use std::{cmp::Ordering, str::FromStr, vec::IntoIter}; use api_models::payouts::PayoutCreateRequest; -use error_stack::{IntoReport, ResultExt}; +use error_stack::{report, ResultExt}; use router_env::{ logger, tracing::{self, instrument}, @@ -83,12 +83,11 @@ pub async fn do_gsm_multiple_connector_actions( retries = retries.map(|i| i - 1); } api_models::gsm::GsmDecision::Requeue => { - Err(errors::ApiErrorResponse::NotImplemented { + Err(report!(errors::ApiErrorResponse::NotImplemented { message: errors::api_error_response::NotImplementedMessage::Reason( "Requeue not implemented".to_string(), ), - }) - .into_report()? + }))? } api_models::gsm::GsmDecision::DoDefault => break, } @@ -150,12 +149,11 @@ pub async fn do_gsm_single_connector_actions( retries = retries.map(|i| i - 1); } api_models::gsm::GsmDecision::Requeue => { - Err(errors::ApiErrorResponse::NotImplemented { + Err(report!(errors::ApiErrorResponse::NotImplemented { message: errors::api_error_response::NotImplementedMessage::Reason( "Requeue not implemented".to_string(), ), - }) - .into_report()? + }))? } api_models::gsm::GsmDecision::DoDefault => break, } @@ -189,7 +187,6 @@ pub async fn get_retries( retries_config .config .parse::() - .into_report() .change_context(errors::ApiErrorResponse::InternalServerError) .attach_printable("Retries config parsing failed") }) @@ -226,9 +223,8 @@ pub fn get_gsm_decision( let option_gsm_decision = option_gsm .and_then(|gsm| { api_models::gsm::GsmDecision::from_str(gsm.decision.as_str()) - .into_report() .map_err(|err| { - let api_error = err.change_context(errors::ApiErrorResponse::InternalServerError) + let api_error = report!(err).change_context(errors::ApiErrorResponse::InternalServerError) .attach_printable("gsm decision parsing failed"); logger::warn!(get_gsm_decision_parse_error=?api_error, "error fetching gsm decision"); api_error diff --git a/crates/router/src/core/pm_auth.rs b/crates/router/src/core/pm_auth.rs index 20db03a26a6..715a7ae12a8 100644 --- a/crates/router/src/core/pm_auth.rs +++ b/crates/router/src/core/pm_auth.rs @@ -17,7 +17,7 @@ use common_utils::{ generate_id, }; use data_models::payments::PaymentIntent; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use helpers::PaymentAuthConnectorDataExt; use masking::{ExposeInterface, PeekInterface, Secret}; use pm_auth::{ @@ -86,8 +86,7 @@ pub async fn create_link_token( }) .ok_or(ApiErrorResponse::GenericNotFoundError { message: "payment method auth connector name not found".to_string(), - }) - .into_report()?; + })?; let connector_name = selected_config.connector_name.as_str(); @@ -323,7 +322,6 @@ async fn store_bank_details_in_payment_methods( .map(|x| x.into_inner().expose()) .map(|v| { serde_json::from_value::(v) - .into_report() .change_context(errors::StorageError::DeserializationFailed) .attach_printable("Failed to deserialize Payment Method Auth config") }) @@ -631,8 +629,7 @@ async fn get_selected_config_from_redis( }) .ok_or(ApiErrorResponse::GenericNotFoundError { message: "payment method auth connector name not found".to_string(), - }) - .into_report()? + })? .clone(); Ok(selected_config) @@ -694,7 +691,6 @@ pub async fn retrieve_payment_method_from_auth_service( && acc.payment_method == auth_token.payment_method }) .ok_or(errors::ApiErrorResponse::InternalServerError) - .into_report() .attach_printable("Bank account details not found")?; let mut bank_type = None; @@ -720,7 +716,6 @@ pub async fn retrieve_payment_method_from_auth_service( .ok_or(errors::ApiErrorResponse::GenericNotFoundError { message: "billing_first_name not found".to_string(), }) - .into_report() .attach_printable("billing_first_name not found")?; let address_details = address.clone().map(|addr| { diff --git a/crates/router/src/core/pm_auth/helpers.rs b/crates/router/src/core/pm_auth/helpers.rs index 43d30705a80..82663169000 100644 --- a/crates/router/src/core/pm_auth/helpers.rs +++ b/crates/router/src/core/pm_auth/helpers.rs @@ -1,5 +1,5 @@ use common_utils::ext_traits::ValueExt; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use pm_auth::types::{self as pm_auth_types, api::BoxedPaymentAuthConnector}; use crate::{ @@ -27,7 +27,6 @@ pub fn get_connector_auth_type( })?; pm_auth_types::ConnectorAuthType::foreign_try_from(auth_type) - .into_report() .change_context(ApiErrorResponse::InternalServerError) .attach_printable("Failed while converting ConnectorAuthType") } diff --git a/crates/router/src/core/refunds.rs b/crates/router/src/core/refunds.rs index 5c2a3070bde..2d6cac3f6e0 100644 --- a/crates/router/src/core/refunds.rs +++ b/crates/router/src/core/refunds.rs @@ -1,7 +1,7 @@ pub mod validator; use common_utils::ext_traits::AsyncExt; -use error_stack::{report, IntoReport, ResultExt}; +use error_stack::{report, ResultExt}; use router_env::{instrument, tracing}; use scheduler::{consumer::types::process_data, utils as process_tracker_utils}; @@ -68,7 +68,6 @@ pub async fn refund_create_core( .amount .or(payment_intent.amount_captured) .ok_or(errors::ApiErrorResponse::InternalServerError) - .into_report() .attach_printable("amount captured is none in a successful payment")?; //[#299]: Can we change the flow based on some workflow idea @@ -134,7 +133,6 @@ pub async fn trigger_refund_to_gateway( .connector .clone() .ok_or(errors::ApiErrorResponse::InternalServerError) - .into_report() .attach_printable("Failed to retrieve connector from payment attempt")?; let storage_scheme = merchant_account.storage_scheme; @@ -637,7 +635,6 @@ pub async fn validate_and_create_refund( .connector .clone() .ok_or(errors::ApiErrorResponse::InternalServerError) - .into_report() .attach_printable("No connector populated in payment attempt")?; let refund_create_req = storage::RefundNew::default() @@ -879,7 +876,6 @@ pub async fn sync_refund_with_gateway_workflow( ) -> Result<(), errors::ProcessTrackerError> { let refund_core = serde_json::from_value::(refund_tracker.tracking_data.clone()) - .into_report() .change_context(errors::ApiErrorResponse::InternalServerError) .attach_printable_lazy(|| { format!( @@ -966,7 +962,6 @@ pub async fn trigger_refund_execute_workflow( let db = &*state.store; let refund_core = serde_json::from_value::(refund_tracker.tracking_data.clone()) - .into_report() .change_context(errors::ApiErrorResponse::InternalServerError) .attach_printable_lazy(|| { format!( diff --git a/crates/router/src/core/refunds/validator.rs b/crates/router/src/core/refunds/validator.rs index cae8f0494be..43d44ebe41d 100644 --- a/crates/router/src/core/refunds/validator.rs +++ b/crates/router/src/core/refunds/validator.rs @@ -1,4 +1,4 @@ -use error_stack::{report, IntoReport}; +use error_stack::report; use router_env::{instrument, tracing}; use time::PrimitiveDateTime; @@ -136,10 +136,10 @@ pub fn validate_for_valid_refunds( || { Err(errors::ApiErrorResponse::RefundNotPossible { connector: connector.to_string(), - }) + } + .into()) }, ) - .into_report() } _ => Ok(()), } diff --git a/crates/router/src/core/routing.rs b/crates/router/src/core/routing.rs index d4e8530de16..31825617398 100644 --- a/crates/router/src/core/routing.rs +++ b/crates/router/src/core/routing.rs @@ -13,14 +13,14 @@ use common_utils::ext_traits::{Encode, StringExt}; use diesel_models::configs; #[cfg(feature = "business_profile_routing")] use diesel_models::routing_algorithm::RoutingAlgorithm; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use rustc_hash::FxHashSet; use super::payments; #[cfg(feature = "payouts")] use super::payouts; #[cfg(feature = "business_profile_routing")] -use crate::types::transformers::{ForeignInto, ForeignTryInto}; +use crate::types::transformers::{ForeignInto, ForeignTryFrom}; use crate::{ consts, core::{ @@ -203,7 +203,6 @@ pub async fn create_routing_config( Err(errors::ApiErrorResponse::PreconditionFailed { message: format!("Reached the maximum number of routing configs ({}), please delete some to create new ones", consts::MAX_ROUTING_CONFIGS_PER_MERCHANT), }) - .into_report() }, )?; let timestamp = common_utils::date_time::now_unix_timestamp(); @@ -304,7 +303,6 @@ pub async fn link_routing_config( Err(errors::ApiErrorResponse::PreconditionFailed { message: "Algorithm is already active".to_string(), }) - .into_report() }, )?; @@ -342,7 +340,6 @@ pub async fn link_routing_config( Err(errors::ApiErrorResponse::PreconditionFailed { message: "Algorithm is already active".to_string(), }) - .into_report() }, )?; let mut merchant_dictionary = @@ -354,7 +351,6 @@ pub async fn link_routing_config( .iter_mut() .find(|rec| rec.id == algorithm_id) .ok_or(errors::ApiErrorResponse::ResourceIdNotFound) - .into_report() .attach_printable("Record with given ID not found for routing config activation")?; record.modified_at = modified_at; @@ -400,8 +396,7 @@ pub async fn retrieve_routing_config( .get_required_value("BusinessProfile") .change_context(errors::ApiErrorResponse::ResourceIdNotFound)?; - let response = routing_algorithm - .foreign_try_into() + let response = routing_types::MerchantRoutingAlgorithm::foreign_try_from(routing_algorithm) .change_context(errors::ApiErrorResponse::InternalServerError) .attach_printable("unable to parse routing algorithm")?; @@ -419,7 +414,6 @@ pub async fn retrieve_routing_config( .into_iter() .find(|rec| rec.id == algorithm_id.0) .ok_or(errors::ApiErrorResponse::ResourceIdNotFound) - .into_report() .attach_printable("Algorithm with the given ID not found in the merchant dictionary")?; let algorithm_config = db @@ -528,8 +522,7 @@ pub async fn unlink_routing_config( } None => Err(errors::ApiErrorResponse::PreconditionFailed { message: "Algorithm is already inactive".to_string(), - }) - .into_report()?, + })?, } } None => Err(errors::ApiErrorResponse::InvalidRequestData { @@ -560,7 +553,6 @@ pub async fn unlink_routing_config( Err(errors::ApiErrorResponse::PreconditionFailed { message: "Algorithm is already inactive".to_string(), }) - .into_report() })?; let routing_algorithm: routing_types::RoutingAlgorithmRef = routing_types::RoutingAlgorithmRef { @@ -576,15 +568,13 @@ pub async fn unlink_routing_config( .ok_or(errors::ApiErrorResponse::PreconditionFailed { // When the merchant_dictionary doesn't have any active algorithm and merchant_account doesn't have any routing_algorithm configured message: "Algorithm is already inactive".to_string(), - }) - .into_report()?; + })?; let record = merchant_dictionary .records .iter_mut() .find(|rec| rec.id == active_algorithm_id) .ok_or(errors::ApiErrorResponse::ResourceIdNotFound) - .into_report() .attach_printable("Record with the given ID not found for de-activation")?; let response = record.clone(); @@ -655,7 +645,6 @@ pub async fn update_default_routing_config( Err(errors::ApiErrorResponse::PreconditionFailed { message: "current config and updated config have different lengths".to_string(), }) - .into_report() })?; let existing_set: FxHashSet = @@ -675,7 +664,6 @@ pub async fn update_default_routing_config( symmetric_diff.join(", ") ), }) - .into_report() })?; helpers::update_merchant_default_config( @@ -781,7 +769,6 @@ pub async fn retrieve_linked_routing_config( .into_iter() .find(|rec| rec.id == algorithm_id) .ok_or(errors::ApiErrorResponse::ResourceIdNotFound) - .into_report() .attach_printable("record for active algorithm not found in merchant dictionary")?; let config = db @@ -885,7 +872,6 @@ pub async fn update_default_routing_config_for_profile( Err(errors::ApiErrorResponse::PreconditionFailed { message: "current config and updated config have different lengths".to_string(), }) - .into_report() })?; let existing_set = FxHashSet::from_iter(default_config.iter().map(|c| { @@ -923,7 +909,6 @@ pub async fn update_default_routing_config_for_profile( Err(errors::ApiErrorResponse::InvalidRequestData { message: format!("connector mismatch between old and new configs ({error_str})"), }) - .into_report() })?; helpers::update_merchant_default_config( diff --git a/crates/router/src/core/surcharge_decision_config.rs b/crates/router/src/core/surcharge_decision_config.rs index a17be6ce36e..b489b92cdf1 100644 --- a/crates/router/src/core/surcharge_decision_config.rs +++ b/crates/router/src/core/surcharge_decision_config.rs @@ -7,7 +7,7 @@ use api_models::{ }; use common_utils::ext_traits::{Encode, StringExt, ValueExt}; use diesel_models::configs; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use euclid::frontend::ast; use super::routing::helpers::{ @@ -53,7 +53,6 @@ pub async fn upsert_surcharge_decision_config( let read_config_key = db.find_config_by_key(&key).await; ast::lowering::lower_program(program.clone()) - .into_report() .change_context(errors::ApiErrorResponse::InvalidRequestData { message: "Invalid Request Data".to_string(), }) diff --git a/crates/router/src/core/user.rs b/crates/router/src/core/user.rs index 703c6443160..2702cec8eb5 100644 --- a/crates/router/src/core/user.rs +++ b/crates/router/src/core/user.rs @@ -2,9 +2,7 @@ use api_models::user::{self as user_api, InviteMultipleUserResponse}; #[cfg(feature = "email")] use diesel_models::user_role::UserRoleUpdate; use diesel_models::{enums::UserStatus, user as storage_user, user_role::UserRoleNew}; -#[cfg(feature = "email")] -use error_stack::IntoReport; -use error_stack::ResultExt; +use error_stack::{report, ResultExt}; use masking::ExposeInterface; #[cfg(feature = "email")] use router_env::env; @@ -219,7 +217,7 @@ pub async fn connect_account( .unwrap_or(false) { if matches!(env::which(), env::Env::Production) { - return Err(UserErrors::InvalidCredentials).into_report(); + return Err(report!(UserErrors::InvalidCredentials)); } let new_user = domain::NewUser::try_from(request)?; @@ -455,7 +453,7 @@ pub async fn invite_user( .to_not_found_response(UserErrors::InvalidRoleId)?; if !role_info.is_invitable() { - return Err(UserErrors::InvalidRoleId.into()) + return Err(report!(UserErrors::InvalidRoleId)) .attach_printable(format!("role_id = {} is not invitable", request.role_id)); } @@ -618,7 +616,7 @@ pub async fn invite_user( }, })) } else { - Err(UserErrors::InternalServerError.into()) + Err(report!(UserErrors::InternalServerError)) } } @@ -628,7 +626,7 @@ pub async fn invite_multiple_user( requests: Vec, ) -> UserResponse> { if requests.len() > 10 { - return Err(UserErrors::MaxInvitationsError.into()) + return Err(report!(UserErrors::MaxInvitationsError)) .attach_printable("Number of invite requests must not exceed 10"); } @@ -672,7 +670,7 @@ async fn handle_invitation( .to_not_found_response(UserErrors::InvalidRoleId)?; if !role_info.is_invitable() { - return Err(UserErrors::InvalidRoleId.into()) + return Err(report!(UserErrors::InvalidRoleId)) .attach_printable(format!("role_id = {} is not invitable", request.role_id)); } @@ -896,7 +894,7 @@ pub async fn resend_invite( })?; if !matches!(user_role.status, UserStatus::InvitationSent) { - return Err(UserErrors::InvalidRoleOperation.into()) + return Err(report!(UserErrors::InvalidRoleOperation)) .attach_printable("User status is not InvitationSent".to_string()); } @@ -1122,7 +1120,7 @@ pub async fn switch_merchant_id( let user_role = active_user_roles .iter() .find(|role| role.merchant_id == request.merchant_id) - .ok_or(UserErrors::InvalidRoleOperation.into()) + .ok_or(report!(UserErrors::InvalidRoleOperation)) .attach_printable("User doesn't have access to switch")?; let token = utils::user::generate_jwt_auth_token(&state, &user, user_role).await?; diff --git a/crates/router/src/core/user/dashboard_metadata.rs b/crates/router/src/core/user/dashboard_metadata.rs index 3f6180158a5..328a54c540b 100644 --- a/crates/router/src/core/user/dashboard_metadata.rs +++ b/crates/router/src/core/user/dashboard_metadata.rs @@ -2,7 +2,7 @@ use api_models::user::dashboard_metadata::{self as api, GetMultipleMetaDataPaylo use diesel_models::{ enums::DashboardMetadata as DBEnum, user::dashboard_metadata::DashboardMetadata, }; -use error_stack::ResultExt; +use error_stack::{report, ResultExt}; #[cfg(feature = "email")] use masking::ExposeInterface; #[cfg(feature = "email")] @@ -61,7 +61,7 @@ fn parse_set_request(data_enum: api::SetMetaDataRequest) -> UserResult { let ip_address = req .ip_address - .ok_or(UserErrors::InternalServerError.into()) + .ok_or(report!(UserErrors::InternalServerError)) .attach_printable("Error Getting Ip Address")?; Ok(types::MetaData::ProductionAgreement( types::ProductionAgreementValue { diff --git a/crates/router/src/core/user_role.rs b/crates/router/src/core/user_role.rs index 587e0e04435..2939c7d51b3 100644 --- a/crates/router/src/core/user_role.rs +++ b/crates/router/src/core/user_role.rs @@ -1,6 +1,6 @@ use api_models::{user as user_api, user_role as user_role_api}; use diesel_models::{enums::UserStatus, user_role::UserRoleUpdate}; -use error_stack::ResultExt; +use error_stack::{report, ResultExt}; use masking::ExposeInterface; use router_env::logger; @@ -61,7 +61,7 @@ pub async fn update_user_role( .to_not_found_response(UserErrors::InvalidRoleId)?; if !role_info.is_updatable() { - return Err(UserErrors::InvalidRoleOperation.into()) + return Err(report!(UserErrors::InvalidRoleOperation)) .attach_printable(format!("User role cannot be updated to {}", req.role_id)); } @@ -72,7 +72,7 @@ pub async fn update_user_role( .attach_printable("User not found in our records".to_string())?; if user_from_token.user_id == user_to_be_updated.get_user_id() { - return Err(UserErrors::InvalidRoleOperation.into()) + return Err(report!(UserErrors::InvalidRoleOperation)) .attach_printable("User Changing their own role"); } @@ -91,7 +91,7 @@ pub async fn update_user_role( .change_context(UserErrors::InternalServerError)?; if !role_to_be_updated.is_updatable() { - return Err(UserErrors::InvalidRoleOperation.into()).attach_printable(format!( + return Err(report!(UserErrors::InvalidRoleOperation)).attach_printable(format!( "User role cannot be updated from {}", role_to_be_updated.get_role_id() )); @@ -122,7 +122,7 @@ pub async fn transfer_org_ownership( req: user_role_api::TransferOrgOwnershipRequest, ) -> UserResponse { if user_from_token.role_id != consts::user_role::ROLE_ID_ORGANIZATION_ADMIN { - return Err(UserErrors::InvalidRoleOperation.into()).attach_printable(format!( + return Err(report!(UserErrors::InvalidRoleOperation)).attach_printable(format!( "role_id = {} is not org_admin", user_from_token.role_id )); @@ -135,7 +135,7 @@ pub async fn transfer_org_ownership( .attach_printable("User not found in our records".to_string())?; if user_from_token.user_id == user_to_be_updated.get_user_id() { - return Err(UserErrors::InvalidRoleOperation.into()) + return Err(report!(UserErrors::InvalidRoleOperation)) .attach_printable("User transferring ownership to themselves".to_string()); } @@ -244,7 +244,7 @@ pub async fn delete_user_role( .into(); if user_from_db.get_user_id() == user_from_token.user_id { - return Err(UserErrors::InvalidDeleteOperation.into()) + return Err(report!(UserErrors::InvalidDeleteOperation)) .attach_printable("User deleting himself"); } @@ -268,12 +268,12 @@ pub async fn delete_user_role( .await .change_context(UserErrors::InternalServerError)?; if !role_info.is_deletable() { - return Err(UserErrors::InvalidDeleteOperation.into()) + return Err(report!(UserErrors::InvalidDeleteOperation)) .attach_printable(format!("role_id = {} is not deletable", user_role.role_id)); } } None => { - return Err(UserErrors::InvalidDeleteOperation.into()) + return Err(report!(UserErrors::InvalidDeleteOperation)) .attach_printable("User is not associated with the merchant"); } }; diff --git a/crates/router/src/core/user_role/role.rs b/crates/router/src/core/user_role/role.rs index 6aa226cd933..a0cf5a6caf9 100644 --- a/crates/router/src/core/user_role/role.rs +++ b/crates/router/src/core/user_role/role.rs @@ -2,7 +2,7 @@ use api_models::user_role::role::{self as role_api}; use common_enums::RoleScope; use common_utils::generate_id_with_default_len; use diesel_models::role::{RoleNew, RoleUpdate}; -use error_stack::ResultExt; +use error_stack::{report, ResultExt}; use crate::{ consts, @@ -73,7 +73,7 @@ pub async fn create_role( if matches!(req.role_scope, RoleScope::Organization) && user_from_token.role_id != consts::user_role::ROLE_ID_ORGANIZATION_ADMIN { - return Err(UserErrors::InvalidRoleOperation.into()) + return Err(report!(UserErrors::InvalidRoleOperation)) .attach_printable("Non org admin user creating org level role"); } @@ -292,7 +292,7 @@ pub async fn update_role( if matches!(role_info.get_scope(), RoleScope::Organization) && user_from_token.role_id != consts::user_role::ROLE_ID_ORGANIZATION_ADMIN { - return Err(UserErrors::InvalidRoleOperation.into()) + return Err(report!(UserErrors::InvalidRoleOperation)) .attach_printable("Non org admin user changing org level role"); } diff --git a/crates/router/src/core/utils.rs b/crates/router/src/core/utils.rs index a64a846930f..3423ace6e5b 100644 --- a/crates/router/src/core/utils.rs +++ b/crates/router/src/core/utils.rs @@ -5,7 +5,7 @@ use common_enums::RequestIncrementalAuthorization; #[cfg(feature = "payouts")] use common_utils::{crypto::Encryptable, pii::Email}; use common_utils::{errors::CustomResult, ext_traits::AsyncExt}; -use error_stack::{report, IntoReport, ResultExt}; +use error_stack::{report, ResultExt}; use router_env::{instrument, tracing}; use uuid::Uuid; @@ -254,7 +254,6 @@ pub async fn construct_refund_router_data<'a, F>( .multiple_api_version_supported_connectors .supported_connectors; let connector_enum = api_models::enums::Connector::from_str(connector_id) - .into_report() .change_context(errors::ConnectorError::InvalidConnectorName) .change_context(errors::ApiErrorResponse::InvalidDataValue { field_name: "connector", @@ -880,7 +879,6 @@ pub async fn construct_retrieve_file_router_data<'a>( .ok_or(errors::ApiErrorResponse::MissingRequiredField { field_name: "profile_id", }) - .into_report() .change_context(errors::ApiErrorResponse::InternalServerError) .attach_printable("profile_id is not set in file_metadata")?; @@ -924,7 +922,6 @@ pub async fn construct_retrieve_file_router_data<'a>( .provider_file_id .clone() .ok_or(errors::ApiErrorResponse::InternalServerError) - .into_report() .attach_printable("Missing provider file id")?, }, response: Err(types::ErrorResponse::default()), @@ -1000,13 +997,13 @@ pub async fn validate_and_get_business_profile( if business_profile.merchant_id.ne(merchant_id) { Err(errors::ApiErrorResponse::AccessForbidden { resource: business_profile.profile_id, - }) + } + .into()) } else { Ok(business_profile) } }) .transpose() - .into_report() } fn connector_needs_business_sub_label(connector_name: &str) -> bool { @@ -1100,7 +1097,6 @@ pub fn get_flow_name() -> RouterResult { .rsplit("::") .next() .ok_or(errors::ApiErrorResponse::InternalServerError) - .into_report() .attach_printable("Flow stringify failed")? .to_string()) } @@ -1113,7 +1109,7 @@ pub fn get_request_incremental_authorization_value( .map(|request_incremental_authorization| { if request_incremental_authorization { if capture_method == Some(common_enums::CaptureMethod::Automatic) { - Err(errors::ApiErrorResponse::NotSupported { message: "incremental authorization is not supported when capture_method is automatic".to_owned() }).into_report()? + Err(errors::ApiErrorResponse::NotSupported { message: "incremental authorization is not supported when capture_method is automatic".to_owned() })? } Ok(RequestIncrementalAuthorization::True) } else { diff --git a/crates/router/src/core/verify_connector.rs b/crates/router/src/core/verify_connector.rs index e837e8b8b25..17cedd1e2d0 100644 --- a/crates/router/src/core/verify_connector.rs +++ b/crates/router/src/core/verify_connector.rs @@ -1,5 +1,5 @@ use api_models::{enums::Connector, verify_connector::VerifyConnectorRequest}; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use crate::{ connector, @@ -25,12 +25,12 @@ pub async fn verify_connector_credentials( ) .change_context(errors::ApiErrorResponse::IncorrectConnectorNameGiven)?; - let card_details = utils::get_test_card_details(req.connector_name)? - .ok_or(errors::ApiErrorResponse::FlowNotSupported { + let card_details = utils::get_test_card_details(req.connector_name)?.ok_or( + errors::ApiErrorResponse::FlowNotSupported { flow: "Verify credentials".to_string(), connector: req.connector_name.to_string(), - }) - .into_report()?; + }, + )?; match req.connector_name { Connector::Stripe => { @@ -57,7 +57,7 @@ pub async fn verify_connector_credentials( _ => Err(errors::ApiErrorResponse::FlowNotSupported { flow: "Verify credentials".to_string(), connector: req.connector_name.to_string(), - }) - .into_report(), + } + .into()), } } diff --git a/crates/router/src/core/webhooks.rs b/crates/router/src/core/webhooks.rs index 6049c8c5081..143d9d8e268 100644 --- a/crates/router/src/core/webhooks.rs +++ b/crates/router/src/core/webhooks.rs @@ -14,7 +14,7 @@ use api_models::{ use common_utils::{ errors::ReportSwitchExt, events::ApiEventsType, ext_traits::Encode, request::RequestContent, }; -use error_stack::{report, IntoReport, ResultExt}; +use error_stack::{report, ResultExt}; use masking::{ExposeInterface, Mask, PeekInterface, Secret}; use router_env::{ instrument, @@ -45,7 +45,7 @@ use crate::{ api::{self, mandates::MandateResponseExt}, domain::{self, types as domain_types}, storage::{self, enums}, - transformers::{ForeignInto, ForeignTryInto}, + transformers::{ForeignInto, ForeignTryFrom}, }, utils::{self as helper_utils, generate_id, OptionExt, ValueExt}, workflows::outgoing_webhook_retry, @@ -150,11 +150,9 @@ pub async fn payments_incoming_webhook_flow( error @ Err(_) => error?, } } - _ => Err(errors::ApiErrorResponse::WebhookProcessingFailure) - .into_report() - .attach_printable( - "Did not get payment id as object reference id in webhook payments flow", - )?, + _ => Err(errors::ApiErrorResponse::WebhookProcessingFailure).attach_printable( + "Did not get payment id as object reference id in webhook payments flow", + )?, }; match payments_response { @@ -194,7 +192,6 @@ pub async fn payments_incoming_webhook_flow( } _ => Err(errors::ApiErrorResponse::WebhookProcessingFailure) - .into_report() .attach_printable("received non-json response from payments core")?, } } @@ -236,7 +233,6 @@ pub async fn refunds_incoming_webhook_flow( .attach_printable("Failed to fetch the refund")?, }, _ => Err(errors::ApiErrorResponse::WebhookProcessingFailure) - .into_report() .attach_printable("received a non-refund id when processing refund webhooks")?, }; let refund_id = refund.refund_id.to_owned(); @@ -245,9 +241,7 @@ pub async fn refunds_incoming_webhook_flow( let refund_update = storage::RefundUpdate::StatusUpdate { connector_refund_id: None, sent_to_gateway: true, - refund_status: event_type - .foreign_try_into() - .into_report() + refund_status: common_enums::RefundStatus::foreign_try_from(event_type) .change_context(errors::ApiErrorResponse::WebhookProcessingFailure) .attach_printable("failed refund status mapping from event type")?, updated_by: merchant_account.storage_scheme.to_string(), @@ -335,7 +329,6 @@ pub async fn get_payment_attempt_from_object_reference_id( .await .to_not_found_response(errors::ApiErrorResponse::WebhookResourceNotFound), _ => Err(errors::ApiErrorResponse::WebhookProcessingFailure) - .into_report() .attach_printable("received a non-payment id for retrieving payment")?, } } @@ -361,9 +354,7 @@ pub async fn get_or_update_dispute_object( amount: dispute_details.amount.clone(), currency: dispute_details.currency, dispute_stage: dispute_details.dispute_stage, - dispute_status: event_type - .foreign_try_into() - .into_report() + dispute_status: common_enums::DisputeStatus::foreign_try_from(event_type) .change_context(errors::ApiErrorResponse::WebhookProcessingFailure) .attach_printable("event type to dispute status mapping failed")?, payment_id: payment_attempt.payment_id.to_owned(), @@ -391,9 +382,7 @@ pub async fn get_or_update_dispute_object( Some(dispute) => { logger::info!("Dispute Already exists, Updating the dispute details"); metrics::INCOMING_DISPUTE_WEBHOOK_UPDATE_RECORD_METRIC.add(&metrics::CONTEXT, 1, &[]); - let dispute_status: diesel_models::enums::DisputeStatus = event_type - .foreign_try_into() - .into_report() + let dispute_status = diesel_models::enums::DisputeStatus::foreign_try_from(event_type) .change_context(errors::ApiErrorResponse::WebhookProcessingFailure) .attach_printable("event type to dispute state conversion failure")?; crate::core::utils::validate_dispute_stage_and_dispute_status( @@ -451,12 +440,9 @@ pub async fn mandates_incoming_webhook_flow( .await .to_not_found_response(errors::ApiErrorResponse::MandateNotFound)?, _ => Err(errors::ApiErrorResponse::WebhookProcessingFailure) - .into_report() .attach_printable("received a non-mandate id for retrieving mandate")?, }; - let mandate_status = event_type - .foreign_try_into() - .into_report() + let mandate_status = common_enums::MandateStatus::foreign_try_from(event_type) .change_context(errors::ApiErrorResponse::WebhookProcessingFailure) .attach_printable("event type to mandate status mapping failed")?; let updated_mandate = db @@ -497,7 +483,9 @@ pub async fn mandates_incoming_webhook_flow( }) } else { logger::error!("Webhook source verification failed for mandates webhook flow"); - Err(errors::ApiErrorResponse::WebhookAuthenticationFailed).into_report() + Err(report!( + errors::ApiErrorResponse::WebhookAuthenticationFailed + )) } } @@ -567,7 +555,9 @@ pub async fn disputes_incoming_webhook_flow( }) } else { metrics::INCOMING_DISPUTE_WEBHOOK_SIGNATURE_FAILURE_METRIC.add(&metrics::CONTEXT, 1, &[]); - Err(errors::ApiErrorResponse::WebhookAuthenticationFailed).into_report() + Err(report!( + errors::ApiErrorResponse::WebhookAuthenticationFailed + )) } } @@ -653,7 +643,6 @@ async fn bank_transfer_webhook_flow( } _ => Err(errors::ApiErrorResponse::WebhookProcessingFailure) - .into_report() .attach_printable("received non-json response from payments core")?, } } @@ -1108,7 +1097,7 @@ async fn trigger_webhook_to_merchant( } enums::WebhookDeliveryAttempt::ManualRetry => { // Will be updated when manual retry is implemented - Err(errors::WebhooksFlowError::NotReceivedByMerchant).into_report()? + Err(errors::WebhooksFlowError::NotReceivedByMerchant)? } } @@ -1126,7 +1115,6 @@ fn raise_webhooks_analytics_event( logger::error!(?error, "Failed to send webhook to merchant"); serde_json::to_value(error.current_context()) - .into_report() .change_context(errors::ApiErrorResponse::WebhookProcessingFailure) .map_err(|error| { logger::error!(?error, "Failed to serialize outgoing webhook error as JSON"); @@ -1178,7 +1166,6 @@ pub async fn webhooks_wrapper Err(errors::ApiErrorResponse::InternalServerError) - .into_report() .attach_printable("Unsupported Flow Type received in incoming webhooks")?, } } else { @@ -1542,7 +1525,6 @@ pub async fn webhooks_core database_call().await, @@ -377,8 +368,7 @@ mod storage { let conn = connection::pg_connection_write(self).await?; storage_types::Address::update_by_address_id(&conn, address_id, address.into()) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) .async_and_then(|address| async { address .convert(key_store.key.get_inner()) @@ -406,8 +396,7 @@ mod storage { address .update(&conn, address_update.into()) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) .async_and_then(|address| async { address .convert(key_store.key.get_inner()) @@ -422,7 +411,6 @@ mod storage { let updated_address = AddressUpdateInternal::from(address_update.clone()) .create_address(address.clone()); let redis_value = serde_json::to_string(&updated_address) - .into_report() .change_context(errors::StorageError::KVError)?; let redis_entry = kv::TypedSql { @@ -477,8 +465,7 @@ mod storage { address_new .insert(&conn) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) .async_and_then(|address| async { address .convert(key_store.key.get_inner()) @@ -535,8 +522,8 @@ mod storage { Ok(HsetnxReply::KeyNotSet) => Err(errors::StorageError::DuplicateValue { entity: "address", key: Some(created_address.address_id), - }) - .into_report(), + } + .into()), Ok(HsetnxReply::KeySet) => Ok(created_address .convert(key_store.key.get_inner()) .await @@ -560,8 +547,7 @@ mod storage { .change_context(errors::StorageError::EncryptionError)? .insert(&conn) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) .async_and_then(|address| async { address .convert(key_store.key.get_inner()) @@ -587,8 +573,7 @@ mod storage { address.into(), ) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) .async_and_then(|addresses| async { let mut output = Vec::with_capacity(addresses.len()); for address in addresses.into_iter() { diff --git a/crates/router/src/db/api_keys.rs b/crates/router/src/db/api_keys.rs index c0d9ea36410..a23b3f0f7af 100644 --- a/crates/router/src/db/api_keys.rs +++ b/crates/router/src/db/api_keys.rs @@ -1,4 +1,4 @@ -use error_stack::IntoReport; +use error_stack::report; use router_env::{instrument, tracing}; #[cfg(feature = "accounts_cache")] use storage_impl::redis::cache::CacheKind; @@ -62,8 +62,7 @@ impl ApiKeyInterface for Store { api_key .insert(&conn) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } #[instrument(skip_all)] @@ -79,8 +78,7 @@ impl ApiKeyInterface for Store { let update_call = || async { storage::ApiKey::update_by_merchant_id_key_id(&conn, merchant_id, key_id, api_key) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) }; #[cfg(not(feature = "accounts_cache"))] @@ -101,8 +99,7 @@ impl ApiKeyInterface for Store { &_key_id, ) .await - .map_err(Into::into) - .into_report()? + .map_err(|error| report!(errors::StorageError::from(error)))? .ok_or(report!(errors::StorageError::ValueNotFound(format!( "ApiKey of {_key_id} not found" ))))?; @@ -126,8 +123,7 @@ impl ApiKeyInterface for Store { let delete_call = || async { storage::ApiKey::revoke_by_merchant_id_key_id(&conn, merchant_id, key_id) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) }; #[cfg(not(feature = "accounts_cache"))] { @@ -145,8 +141,7 @@ impl ApiKeyInterface for Store { let api_key = storage::ApiKey::find_optional_by_merchant_id_key_id(&conn, merchant_id, key_id) .await - .map_err(Into::into) - .into_report()? + .map_err(|error| report!(errors::StorageError::from(error)))? .ok_or(report!(errors::StorageError::ValueNotFound(format!( "ApiKey of {key_id} not found" ))))?; @@ -169,8 +164,7 @@ impl ApiKeyInterface for Store { let conn = connection::pg_connection_read(self).await?; storage::ApiKey::find_optional_by_merchant_id_key_id(&conn, merchant_id, key_id) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } #[instrument(skip_all)] @@ -183,8 +177,7 @@ impl ApiKeyInterface for Store { let conn = connection::pg_connection_read(self).await?; storage::ApiKey::find_optional_by_hashed_api_key(&conn, hashed_api_key) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) }; #[cfg(not(feature = "accounts_cache"))] @@ -214,8 +207,7 @@ impl ApiKeyInterface for Store { let conn = connection::pg_connection_read(self).await?; storage::ApiKey::find_by_merchant_id(&conn, merchant_id, limit, offset) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } } diff --git a/crates/router/src/db/authentication.rs b/crates/router/src/db/authentication.rs index 14604684863..a2c7f050052 100644 --- a/crates/router/src/db/authentication.rs +++ b/crates/router/src/db/authentication.rs @@ -1,5 +1,5 @@ use diesel_models::authentication::AuthenticationUpdateInternal; -use error_stack::IntoReport; +use error_stack::report; use router_env::{instrument, tracing}; use super::{MockDb, Store}; @@ -40,8 +40,7 @@ impl AuthenticationInterface for Store { authentication .insert(&conn) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } #[instrument(skip_all)] @@ -57,8 +56,7 @@ impl AuthenticationInterface for Store { &authentication_id, ) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } #[instrument(skip_all)] @@ -75,8 +73,7 @@ impl AuthenticationInterface for Store { authentication_update, ) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } } diff --git a/crates/router/src/db/authorization.rs b/crates/router/src/db/authorization.rs index 322be5fc6db..7b7802d64e5 100644 --- a/crates/router/src/db/authorization.rs +++ b/crates/router/src/db/authorization.rs @@ -1,5 +1,5 @@ use diesel_models::authorization::AuthorizationUpdateInternal; -use error_stack::IntoReport; +use error_stack::report; use router_env::{instrument, tracing}; use super::{MockDb, Store}; @@ -41,8 +41,7 @@ impl AuthorizationInterface for Store { authorization .insert(&conn) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } #[instrument(skip_all)] @@ -54,8 +53,7 @@ impl AuthorizationInterface for Store { let conn = connection::pg_connection_read(self).await?; storage::Authorization::find_by_merchant_id_payment_id(&conn, merchant_id, payment_id) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } #[instrument(skip_all)] @@ -73,8 +71,7 @@ impl AuthorizationInterface for Store { authorization, ) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } } diff --git a/crates/router/src/db/blocklist.rs b/crates/router/src/db/blocklist.rs index 083c988b8d5..4a7236c95a7 100644 --- a/crates/router/src/db/blocklist.rs +++ b/crates/router/src/db/blocklist.rs @@ -1,4 +1,4 @@ -use error_stack::IntoReport; +use error_stack::report; use router_env::{instrument, tracing}; use storage_impl::MockDb; @@ -54,8 +54,7 @@ impl BlocklistInterface for Store { pm_blocklist .insert(&conn) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } #[instrument(skip_all)] @@ -67,8 +66,7 @@ impl BlocklistInterface for Store { let conn = connection::pg_connection_write(self).await?; storage::Blocklist::find_by_merchant_id_fingerprint_id(&conn, merchant_id, fingerprint_id) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } #[instrument(skip_all)] @@ -79,8 +77,7 @@ impl BlocklistInterface for Store { let conn = connection::pg_connection_write(self).await?; storage::Blocklist::list_by_merchant_id(&conn, merchant_id) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } #[instrument(skip_all)] @@ -100,8 +97,7 @@ impl BlocklistInterface for Store { offset, ) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } #[instrument(skip_all)] @@ -113,8 +109,7 @@ impl BlocklistInterface for Store { let conn = connection::pg_connection_write(self).await?; storage::Blocklist::delete_by_merchant_id_fingerprint_id(&conn, merchant_id, fingerprint_id) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } } diff --git a/crates/router/src/db/blocklist_fingerprint.rs b/crates/router/src/db/blocklist_fingerprint.rs index 1be6f60e877..65671555c7f 100644 --- a/crates/router/src/db/blocklist_fingerprint.rs +++ b/crates/router/src/db/blocklist_fingerprint.rs @@ -1,4 +1,4 @@ -use error_stack::IntoReport; +use error_stack::report; use router_env::{instrument, tracing}; use storage_impl::MockDb; @@ -35,8 +35,7 @@ impl BlocklistFingerprintInterface for Store { pm_fingerprint_new .insert(&conn) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } #[instrument(skip_all)] @@ -52,8 +51,7 @@ impl BlocklistFingerprintInterface for Store { fingerprint_id, ) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } } diff --git a/crates/router/src/db/blocklist_lookup.rs b/crates/router/src/db/blocklist_lookup.rs index ad8315b757d..0f796946beb 100644 --- a/crates/router/src/db/blocklist_lookup.rs +++ b/crates/router/src/db/blocklist_lookup.rs @@ -1,4 +1,4 @@ -use error_stack::IntoReport; +use error_stack::report; use router_env::{instrument, tracing}; use storage_impl::MockDb; @@ -41,8 +41,7 @@ impl BlocklistLookupInterface for Store { blocklist_lookup_entry .insert(&conn) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } #[instrument(skip_all)] @@ -54,8 +53,7 @@ impl BlocklistLookupInterface for Store { let conn = connection::pg_connection_read(self).await?; storage::BlocklistLookup::find_by_merchant_id_fingerprint(&conn, merchant_id, fingerprint) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } #[instrument(skip_all)] @@ -67,8 +65,7 @@ impl BlocklistLookupInterface for Store { let conn = connection::pg_connection_write(self).await?; storage::BlocklistLookup::delete_by_merchant_id_fingerprint(&conn, merchant_id, fingerprint) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } } diff --git a/crates/router/src/db/business_profile.rs b/crates/router/src/db/business_profile.rs index e0e00464541..4d5a94b370a 100644 --- a/crates/router/src/db/business_profile.rs +++ b/crates/router/src/db/business_profile.rs @@ -1,4 +1,4 @@ -use error_stack::IntoReport; +use error_stack::report; use router_env::{instrument, tracing}; use super::Store; @@ -56,8 +56,7 @@ impl BusinessProfileInterface for Store { business_profile .insert(&conn) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } #[instrument(skip_all)] @@ -68,8 +67,7 @@ impl BusinessProfileInterface for Store { let conn = connection::pg_connection_read(self).await?; storage::business_profile::BusinessProfile::find_by_profile_id(&conn, profile_id) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } #[instrument(skip_all)] @@ -85,8 +83,7 @@ impl BusinessProfileInterface for Store { merchant_id, ) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } #[instrument(skip_all)] @@ -102,8 +99,7 @@ impl BusinessProfileInterface for Store { business_profile_update, ) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } #[instrument(skip_all)] @@ -119,8 +115,7 @@ impl BusinessProfileInterface for Store { merchant_id, ) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } #[instrument(skip_all)] @@ -134,8 +129,7 @@ impl BusinessProfileInterface for Store { merchant_id, ) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } } diff --git a/crates/router/src/db/capture.rs b/crates/router/src/db/capture.rs index 1373b45c2cd..48aad6a9e3f 100644 --- a/crates/router/src/db/capture.rs +++ b/crates/router/src/db/capture.rs @@ -32,7 +32,7 @@ pub trait CaptureInterface { #[cfg(feature = "kv_store")] mod storage { - use error_stack::IntoReport; + use error_stack::report; use router_env::{instrument, tracing}; use super::CaptureInterface; @@ -56,8 +56,7 @@ mod storage { capture .insert(&conn) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) }; db_call().await } @@ -73,8 +72,7 @@ mod storage { let conn = connection::pg_connection_write(self).await?; this.update_with_capture_id(&conn, capture) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) }; db_call().await } @@ -96,8 +94,7 @@ mod storage { &conn, ) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) }; db_call().await } @@ -106,7 +103,7 @@ mod storage { #[cfg(not(feature = "kv_store"))] mod storage { - use error_stack::IntoReport; + use error_stack::report; use router_env::{instrument, tracing}; use super::CaptureInterface; @@ -130,8 +127,7 @@ mod storage { capture .insert(&conn) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) }; db_call().await } @@ -147,8 +143,7 @@ mod storage { let conn = connection::pg_connection_write(self).await?; this.update_with_capture_id(&conn, capture) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) }; db_call().await } @@ -170,8 +165,7 @@ mod storage { &conn, ) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) }; db_call().await } diff --git a/crates/router/src/db/cards_info.rs b/crates/router/src/db/cards_info.rs index 97a0c6c7c7f..68bd90946b6 100644 --- a/crates/router/src/db/cards_info.rs +++ b/crates/router/src/db/cards_info.rs @@ -1,4 +1,4 @@ -use error_stack::IntoReport; +use error_stack::report; use router_env::{instrument, tracing}; use crate::{ @@ -27,8 +27,7 @@ impl CardsInfoInterface for Store { let conn = connection::pg_connection_read(self).await?; CardInfo::find_by_iin(&conn, card_iin) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } } diff --git a/crates/router/src/db/configs.rs b/crates/router/src/db/configs.rs index 3f49254ae44..8deb4bdf6f6 100644 --- a/crates/router/src/db/configs.rs +++ b/crates/router/src/db/configs.rs @@ -1,6 +1,6 @@ use common_utils::ext_traits::AsyncExt; use diesel_models::configs::ConfigUpdateInternal; -use error_stack::{IntoReport, ResultExt}; +use error_stack::{report, ResultExt}; use router_env::{instrument, tracing}; use storage_impl::redis::{ cache::{CacheKind, CONFIG_CACHE}, @@ -65,7 +65,10 @@ impl ConfigInterface for Store { config: storage::ConfigNew, ) -> CustomResult { let conn = connection::pg_connection_write(self).await?; - config.insert(&conn).await.map_err(Into::into).into_report() + config + .insert(&conn) + .await + .map_err(|error| report!(errors::StorageError::from(error))) } #[instrument(skip_all)] @@ -77,8 +80,7 @@ impl ConfigInterface for Store { let conn = connection::pg_connection_write(self).await?; storage::Config::update_by_key(&conn, key, config_update) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } //update in DB and remove in redis and cache @@ -102,8 +104,7 @@ impl ConfigInterface for Store { let conn = connection::pg_connection_write(self).await?; storage::Config::find_by_key(&conn, key) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } //check in cache, then redis then finally DB, and on the way back populate redis and cache @@ -116,8 +117,7 @@ impl ConfigInterface for Store { let conn = connection::pg_connection_write(self).await?; storage::Config::find_by_key(&conn, key) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) }; cache::get_or_populate_in_memory(self, key, find_config_by_key_from_db, &CONFIG_CACHE).await } @@ -133,8 +133,7 @@ impl ConfigInterface for Store { let conn = connection::pg_connection_write(self).await?; match storage::Config::find_by_key(&conn, key) .await - .map_err(Into::::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) { Ok(a) => Ok(a), Err(err) => { @@ -148,8 +147,7 @@ impl ConfigInterface for Store { } .insert(&conn) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) }) .await } else { @@ -170,8 +168,7 @@ impl ConfigInterface for Store { let conn = connection::pg_connection_write(self).await?; let deleted = storage::Config::delete_by_key(&conn, key) .await - .map_err(Into::into) - .into_report()?; + .map_err(|error| report!(errors::StorageError::from(error)))?; self.get_redis_conn() .map_err(Into::::into)? @@ -193,11 +190,7 @@ impl ConfigInterface for MockDb { let mut configs = self.configs.lock().await; let config_new = storage::Config { - id: configs - .len() - .try_into() - .into_report() - .change_context(errors::StorageError::MockDbError)?, + id: i32::try_from(configs.len()).change_context(errors::StorageError::MockDbError)?, key: config.key, config: config.config, }; diff --git a/crates/router/src/db/customers.rs b/crates/router/src/db/customers.rs index 9385e237e69..081a41e0073 100644 --- a/crates/router/src/db/customers.rs +++ b/crates/router/src/db/customers.rs @@ -1,5 +1,5 @@ use common_utils::ext_traits::AsyncExt; -use error_stack::{IntoReport, ResultExt}; +use error_stack::{report, ResultExt}; use futures::future::try_join_all; use masking::PeekInterface; use router_env::{instrument, tracing}; @@ -83,8 +83,7 @@ impl CustomerInterface for Store { merchant_id, ) .await - .map_err(Into::into) - .into_report()? + .map_err(|error| report!(errors::StorageError::from(error)))? .async_map(|c| async { c.convert(key_store.key.get_inner()) .await @@ -120,8 +119,7 @@ impl CustomerInterface for Store { customer.into(), ) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) .async_and_then(|c| async { c.convert(key_store.key.get_inner()) .await @@ -141,8 +139,7 @@ impl CustomerInterface for Store { let customer: domain::Customer = storage::Customer::find_by_customer_id_merchant_id(&conn, customer_id, merchant_id) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) .async_and_then(|c| async { c.convert(key_store.key.get_inner()) .await @@ -167,8 +164,7 @@ impl CustomerInterface for Store { let encrypted_customers = storage::Customer::list_by_merchant_id(&conn, merchant_id) .await - .map_err(Into::into) - .into_report()?; + .map_err(|error| report!(errors::StorageError::from(error)))?; let customers = try_join_all(encrypted_customers.into_iter().map( |encrypted_customer| async { @@ -196,8 +192,7 @@ impl CustomerInterface for Store { .change_context(errors::StorageError::EncryptionError)? .insert(&conn) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) .async_and_then(|c| async { c.convert(key_store.key.get_inner()) .await @@ -215,8 +210,7 @@ impl CustomerInterface for Store { let conn = connection::pg_connection_write(self).await?; storage::Customer::delete_by_customer_id_merchant_id(&conn, customer_id, merchant_id) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } } diff --git a/crates/router/src/db/dashboard_metadata.rs b/crates/router/src/db/dashboard_metadata.rs index fee09870d59..5267985e1ac 100644 --- a/crates/router/src/db/dashboard_metadata.rs +++ b/crates/router/src/db/dashboard_metadata.rs @@ -1,5 +1,5 @@ use diesel_models::{enums, user::dashboard_metadata as storage}; -use error_stack::{IntoReport, ResultExt}; +use error_stack::{report, ResultExt}; use router_env::{instrument, tracing}; use storage_impl::MockDb; @@ -65,8 +65,7 @@ impl DashboardMetadataInterface for Store { metadata .insert(&conn) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } #[instrument(skip_all)] @@ -88,8 +87,7 @@ impl DashboardMetadataInterface for Store { dashboard_metadata_update, ) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } #[instrument(skip_all)] @@ -109,8 +107,7 @@ impl DashboardMetadataInterface for Store { data_keys, ) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } #[instrument(skip_all)] @@ -128,8 +125,7 @@ impl DashboardMetadataInterface for Store { data_keys, ) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } #[instrument(skip_all)] @@ -145,8 +141,7 @@ impl DashboardMetadataInterface for Store { merchant_id.to_owned(), ) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } #[instrument(skip_all)] @@ -164,8 +159,7 @@ impl DashboardMetadataInterface for Store { data_key, ) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } } @@ -188,10 +182,7 @@ impl DashboardMetadataInterface for MockDb { })? } let metadata_new = storage::DashboardMetadata { - id: dashboard_metadata - .len() - .try_into() - .into_report() + id: i32::try_from(dashboard_metadata.len()) .change_context(errors::StorageError::MockDbError)?, user_id: metadata.user_id, merchant_id: metadata.merchant_id, diff --git a/crates/router/src/db/dispute.rs b/crates/router/src/db/dispute.rs index b0d0594c013..0fe5f3d7666 100644 --- a/crates/router/src/db/dispute.rs +++ b/crates/router/src/db/dispute.rs @@ -1,4 +1,4 @@ -use error_stack::{IntoReport, ResultExt}; +use error_stack::{report, ResultExt}; use router_env::{instrument, tracing}; use super::{MockDb, Store}; @@ -58,8 +58,7 @@ impl DisputeInterface for Store { dispute .insert(&conn) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } #[instrument(skip_all)] @@ -77,8 +76,7 @@ impl DisputeInterface for Store { connector_dispute_id, ) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } #[instrument(skip_all)] @@ -90,8 +88,7 @@ impl DisputeInterface for Store { let conn = connection::pg_connection_read(self).await?; storage::Dispute::find_by_merchant_id_dispute_id(&conn, merchant_id, dispute_id) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } #[instrument(skip_all)] @@ -103,8 +100,7 @@ impl DisputeInterface for Store { let conn = connection::pg_connection_read(self).await?; storage::Dispute::filter_by_constraints(&conn, merchant_id, dispute_constraints) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } #[instrument(skip_all)] @@ -116,8 +112,7 @@ impl DisputeInterface for Store { let conn = connection::pg_connection_read(self).await?; storage::Dispute::find_by_merchant_id_payment_id(&conn, merchant_id, payment_id) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } #[instrument(skip_all)] @@ -129,8 +124,7 @@ impl DisputeInterface for Store { let conn = connection::pg_connection_write(self).await?; this.update(&conn, dispute) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } } @@ -154,10 +148,7 @@ impl DisputeInterface for MockDb { let now = common_utils::date_time::now(); let new_dispute = storage::Dispute { - id: locked_disputes - .len() - .try_into() - .into_report() + id: i32::try_from(locked_disputes.len()) .change_context(errors::StorageError::MockDbError)?, dispute_id: dispute.dispute_id, amount: dispute.amount, diff --git a/crates/router/src/db/events.rs b/crates/router/src/db/events.rs index f3df7278029..53480ed431b 100644 --- a/crates/router/src/db/events.rs +++ b/crates/router/src/db/events.rs @@ -1,5 +1,5 @@ use common_utils::ext_traits::AsyncExt; -use error_stack::{IntoReport, ResultExt}; +use error_stack::{report, ResultExt}; use router_env::{instrument, tracing}; use super::{MockDb, Store}; @@ -106,8 +106,7 @@ impl EventInterface for Store { .change_context(errors::StorageError::EncryptionError)? .insert(&conn) .await - .map_err(Into::into) - .into_report()? + .map_err(|error| report!(errors::StorageError::from(error)))? .convert(merchant_key_store.key.get_inner()) .await .change_context(errors::StorageError::DecryptionError) @@ -123,8 +122,7 @@ impl EventInterface for Store { let conn = connection::pg_connection_read(self).await?; storage::Event::find_by_merchant_id_event_id(&conn, merchant_id, event_id) .await - .map_err(Into::into) - .into_report()? + .map_err(|error| report!(errors::StorageError::from(error)))? .convert(merchant_key_store.key.get_inner()) .await .change_context(errors::StorageError::DecryptionError) @@ -144,8 +142,7 @@ impl EventInterface for Store { primary_object_id, ) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) .async_and_then(|events| async { let mut domain_events = Vec::with_capacity(events.len()); for event in events.into_iter() { @@ -181,8 +178,7 @@ impl EventInterface for Store { offset, ) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) .async_and_then(|events| async { let mut domain_events = Vec::with_capacity(events.len()); for event in events.into_iter() { @@ -212,8 +208,7 @@ impl EventInterface for Store { initial_attempt_id, ) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) .async_and_then(|events| async { let mut domain_events = Vec::with_capacity(events.len()); for event in events.into_iter() { @@ -243,8 +238,7 @@ impl EventInterface for Store { primary_object_id, ) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) .async_and_then(|events| async { let mut domain_events = Vec::with_capacity(events.len()); for event in events.into_iter() { @@ -280,8 +274,7 @@ impl EventInterface for Store { offset, ) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) .async_and_then(|events| async { let mut domain_events = Vec::with_capacity(events.len()); for event in events.into_iter() { @@ -307,8 +300,7 @@ impl EventInterface for Store { let conn = connection::pg_connection_read(self).await?; storage::Event::list_by_profile_id_initial_attempt_id(&conn, profile_id, initial_attempt_id) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) .async_and_then(|events| async { let mut domain_events = Vec::with_capacity(events.len()); for event in events.into_iter() { @@ -335,8 +327,7 @@ impl EventInterface for Store { let conn = connection::pg_connection_write(self).await?; storage::Event::update_by_merchant_id_event_id(&conn, merchant_id, event_id, event.into()) .await - .map_err(Into::into) - .into_report()? + .map_err(|error| report!(errors::StorageError::from(error)))? .convert(merchant_key_store.key.get_inner()) .await .change_context(errors::StorageError::DecryptionError) diff --git a/crates/router/src/db/file.rs b/crates/router/src/db/file.rs index ffd18336efa..da28404971d 100644 --- a/crates/router/src/db/file.rs +++ b/crates/router/src/db/file.rs @@ -1,4 +1,4 @@ -use error_stack::IntoReport; +use error_stack::report; use router_env::{instrument, tracing}; use super::{MockDb, Store}; @@ -42,7 +42,9 @@ impl FileMetadataInterface for Store { file: storage::FileMetadataNew, ) -> CustomResult { let conn = connection::pg_connection_write(self).await?; - file.insert(&conn).await.map_err(Into::into).into_report() + file.insert(&conn) + .await + .map_err(|error| report!(errors::StorageError::from(error))) } #[instrument(skip_all)] @@ -54,8 +56,7 @@ impl FileMetadataInterface for Store { let conn = connection::pg_connection_read(self).await?; storage::FileMetadata::find_by_merchant_id_file_id(&conn, merchant_id, file_id) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } #[instrument(skip_all)] @@ -67,8 +68,7 @@ impl FileMetadataInterface for Store { let conn = connection::pg_connection_write(self).await?; storage::FileMetadata::delete_by_merchant_id_file_id(&conn, merchant_id, file_id) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } #[instrument(skip_all)] @@ -80,8 +80,7 @@ impl FileMetadataInterface for Store { let conn = connection::pg_connection_write(self).await?; this.update(&conn, file_metadata) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } } diff --git a/crates/router/src/db/fraud_check.rs b/crates/router/src/db/fraud_check.rs index 656cac0adb5..34818260364 100644 --- a/crates/router/src/db/fraud_check.rs +++ b/crates/router/src/db/fraud_check.rs @@ -1,5 +1,5 @@ use diesel_models::fraud_check::{self as storage, FraudCheck, FraudCheckUpdate}; -use error_stack::IntoReport; +use error_stack::report; use router_env::{instrument, tracing}; use super::MockDb; @@ -43,7 +43,9 @@ impl FraudCheckInterface for Store { new: storage::FraudCheckNew, ) -> CustomResult { let conn = connection::pg_connection_write(self).await?; - new.insert(&conn).await.map_err(Into::into).into_report() + new.insert(&conn) + .await + .map_err(|error| report!(errors::StorageError::from(error))) } #[instrument(skip_all)] @@ -55,8 +57,7 @@ impl FraudCheckInterface for Store { let conn = connection::pg_connection_write(self).await?; this.update_with_attempt_id(&conn, fraud_check) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } #[instrument(skip_all)] @@ -68,8 +69,7 @@ impl FraudCheckInterface for Store { let conn = connection::pg_connection_write(self).await?; FraudCheck::get_with_payment_id(&conn, payment_id, merchant_id) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } #[instrument(skip_all)] @@ -81,8 +81,7 @@ impl FraudCheckInterface for Store { let conn = connection::pg_connection_write(self).await?; FraudCheck::get_with_payment_id_if_present(&conn, payment_id, merchant_id) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } } diff --git a/crates/router/src/db/gsm.rs b/crates/router/src/db/gsm.rs index 4a9cf651d2b..1aa96e14c18 100644 --- a/crates/router/src/db/gsm.rs +++ b/crates/router/src/db/gsm.rs @@ -1,5 +1,5 @@ use diesel_models::gsm as storage; -use error_stack::IntoReport; +use error_stack::report; use router_env::{instrument, tracing}; use super::MockDb; @@ -59,7 +59,9 @@ impl GsmInterface for Store { rule: storage::GatewayStatusMappingNew, ) -> CustomResult { let conn = connection::pg_connection_write(self).await?; - rule.insert(&conn).await.map_err(Into::into).into_report() + rule.insert(&conn) + .await + .map_err(|error| report!(errors::StorageError::from(error))) } #[instrument(skip_all)] @@ -76,8 +78,7 @@ impl GsmInterface for Store { &conn, connector, flow, sub_flow, code, message, ) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } #[instrument(skip_all)] @@ -92,8 +93,7 @@ impl GsmInterface for Store { let conn = connection::pg_connection_read(self).await?; storage::GatewayStatusMap::find(&conn, connector, flow, sub_flow, code, message) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } #[instrument(skip_all)] @@ -109,8 +109,7 @@ impl GsmInterface for Store { let conn = connection::pg_connection_write(self).await?; storage::GatewayStatusMap::update(&conn, connector, flow, sub_flow, code, message, data) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } #[instrument(skip_all)] @@ -125,8 +124,7 @@ impl GsmInterface for Store { let conn = connection::pg_connection_write(self).await?; storage::GatewayStatusMap::delete(&conn, connector, flow, sub_flow, code, message) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } } diff --git a/crates/router/src/db/locker_mock_up.rs b/crates/router/src/db/locker_mock_up.rs index d70c6baa815..ea0e70c5bb9 100644 --- a/crates/router/src/db/locker_mock_up.rs +++ b/crates/router/src/db/locker_mock_up.rs @@ -1,4 +1,4 @@ -use error_stack::{IntoReport, ResultExt}; +use error_stack::{report, ResultExt}; use router_env::{instrument, tracing}; use super::{MockDb, Store}; @@ -36,8 +36,7 @@ impl LockerMockUpInterface for Store { let conn = connection::pg_connection_read(self).await?; storage::LockerMockUp::find_by_card_id(&conn, card_id) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } #[instrument(skip_all)] @@ -46,7 +45,9 @@ impl LockerMockUpInterface for Store { new: storage::LockerMockUpNew, ) -> CustomResult { let conn = connection::pg_connection_write(self).await?; - new.insert(&conn).await.map_err(Into::into).into_report() + new.insert(&conn) + .await + .map_err(|error| report!(errors::StorageError::from(error))) } #[instrument(skip_all)] @@ -57,8 +58,7 @@ impl LockerMockUpInterface for Store { let conn = connection::pg_connection_write(self).await?; storage::LockerMockUp::delete_by_card_id(&conn, card_id) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } } @@ -88,10 +88,7 @@ impl LockerMockUpInterface for MockDb { } let created_locker = storage::LockerMockUp { - id: locked_lockers - .len() - .try_into() - .into_report() + id: i32::try_from(locked_lockers.len()) .change_context(errors::StorageError::MockDbError)?, card_id: new.card_id, external_id: new.external_id, diff --git a/crates/router/src/db/mandate.rs b/crates/router/src/db/mandate.rs index 936344f5af5..273d34a68af 100644 --- a/crates/router/src/db/mandate.rs +++ b/crates/router/src/db/mandate.rs @@ -1,4 +1,4 @@ -use error_stack::{IntoReport, ResultExt}; +use error_stack::{report, ResultExt}; use router_env::{instrument, tracing}; use super::{MockDb, Store}; @@ -58,8 +58,7 @@ impl MandateInterface for Store { let conn = connection::pg_connection_read(self).await?; storage::Mandate::find_by_merchant_id_mandate_id(&conn, merchant_id, mandate_id) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } #[instrument(skip_all)] @@ -75,8 +74,7 @@ impl MandateInterface for Store { connector_mandate_id, ) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } #[instrument(skip_all)] @@ -88,8 +86,7 @@ impl MandateInterface for Store { let conn = connection::pg_connection_read(self).await?; storage::Mandate::find_by_merchant_id_customer_id(&conn, merchant_id, customer_id) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } #[instrument(skip_all)] @@ -102,8 +99,7 @@ impl MandateInterface for Store { let conn = connection::pg_connection_write(self).await?; storage::Mandate::update_by_merchant_id_mandate_id(&conn, merchant_id, mandate_id, mandate) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } #[instrument(skip_all)] @@ -115,8 +111,7 @@ impl MandateInterface for Store { let conn = connection::pg_connection_read(self).await?; storage::Mandate::filter_by_constraints(&conn, merchant_id, mandate_constraints) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } #[instrument(skip_all)] @@ -128,8 +123,7 @@ impl MandateInterface for Store { mandate .insert(&conn) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } } @@ -288,11 +282,7 @@ impl MandateInterface for MockDb { ) -> CustomResult { let mut mandates = self.mandates.lock().await; let mandate = storage::Mandate { - id: mandates - .len() - .try_into() - .into_report() - .change_context(errors::StorageError::MockDbError)?, + id: i32::try_from(mandates.len()).change_context(errors::StorageError::MockDbError)?, mandate_id: mandate_new.mandate_id.clone(), customer_id: mandate_new.customer_id, merchant_id: mandate_new.merchant_id, diff --git a/crates/router/src/db/merchant_account.rs b/crates/router/src/db/merchant_account.rs index 3ecf897148e..08d0c279047 100644 --- a/crates/router/src/db/merchant_account.rs +++ b/crates/router/src/db/merchant_account.rs @@ -2,7 +2,7 @@ use std::collections::HashMap; use common_utils::ext_traits::AsyncExt; -use error_stack::{IntoReport, ResultExt}; +use error_stack::{report, ResultExt}; use router_env::{instrument, tracing}; #[cfg(feature = "accounts_cache")] use storage_impl::redis::cache::{CacheKind, ACCOUNTS_CACHE}; @@ -92,8 +92,7 @@ impl MerchantAccountInterface for Store { .change_context(errors::StorageError::EncryptionError)? .insert(&conn) .await - .map_err(Into::into) - .into_report()? + .map_err(|error| report!(errors::StorageError::from(error)))? .convert(merchant_key_store.key.get_inner()) .await .change_context(errors::StorageError::DecryptionError) @@ -109,8 +108,7 @@ impl MerchantAccountInterface for Store { let conn = connection::pg_connection_read(self).await?; storage::MerchantAccount::find_by_merchant_id(&conn, merchant_id) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) }; #[cfg(not(feature = "accounts_cache"))] @@ -146,8 +144,7 @@ impl MerchantAccountInterface for Store { .change_context(errors::StorageError::EncryptionError)? .update(&conn, merchant_account.into()) .await - .map_err(Into::into) - .into_report()?; + .map_err(|error| report!(errors::StorageError::from(error)))?; #[cfg(feature = "accounts_cache")] { @@ -173,8 +170,7 @@ impl MerchantAccountInterface for Store { merchant_account.into(), ) .await - .map_err(Into::into) - .into_report()?; + .map_err(|error| report!(errors::StorageError::from(error)))?; #[cfg(feature = "accounts_cache")] { @@ -196,8 +192,7 @@ impl MerchantAccountInterface for Store { storage::MerchantAccount::find_by_publishable_key(&conn, publishable_key) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) }; let merchant_account; @@ -245,8 +240,7 @@ impl MerchantAccountInterface for Store { let encrypted_merchant_accounts = storage::MerchantAccount::list_by_organization_id(&conn, organization_id) .await - .map_err(Into::into) - .into_report()?; + .map_err(|error| report!(errors::StorageError::from(error)))?; let db_master_key = self.get_master_key().to_vec().into(); @@ -285,8 +279,7 @@ impl MerchantAccountInterface for Store { let is_deleted_func = || async { storage::MerchantAccount::delete_by_merchant_id(&conn, merchant_id) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) }; let is_deleted; @@ -301,8 +294,7 @@ impl MerchantAccountInterface for Store { let merchant_account = storage::MerchantAccount::find_by_merchant_id(&conn, merchant_id) .await - .map_err(Into::into) - .into_report()?; + .map_err(|error| report!(errors::StorageError::from(error)))?; is_deleted = is_deleted_func().await?; @@ -323,8 +315,7 @@ impl MerchantAccountInterface for Store { let encrypted_merchant_accounts = storage::MerchantAccount::list_multiple_merchant_accounts(&conn, merchant_ids) .await - .map_err(Into::into) - .into_report()?; + .map_err(|error| report!(errors::StorageError::from(error)))?; let db_master_key = self.get_master_key().to_vec().into(); @@ -375,11 +366,7 @@ impl MerchantAccountInterface for MockDb { ) -> CustomResult { let mut accounts = self.merchant_accounts.lock().await; merchant_account.id.get_or_insert( - accounts - .len() - .try_into() - .into_report() - .change_context(errors::StorageError::MockDbError)?, + i32::try_from(accounts.len()).change_context(errors::StorageError::MockDbError)?, ); let account = Conversion::convert(merchant_account) .await diff --git a/crates/router/src/db/merchant_connector_account.rs b/crates/router/src/db/merchant_connector_account.rs index e4cad30ec29..b7c85560804 100644 --- a/crates/router/src/db/merchant_connector_account.rs +++ b/crates/router/src/db/merchant_connector_account.rs @@ -1,5 +1,5 @@ use common_utils::ext_traits::{AsyncExt, ByteSliceExt, Encode}; -use error_stack::{IntoReport, ResultExt}; +use error_stack::{report, ResultExt}; use router_env::{instrument, tracing}; #[cfg(feature = "accounts_cache")] use storage_impl::redis::cache; @@ -183,8 +183,7 @@ impl MerchantConnectorAccountInterface for Store { connector_label, ) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) }; #[cfg(not(feature = "accounts_cache"))] @@ -229,8 +228,7 @@ impl MerchantConnectorAccountInterface for Store { connector_name, ) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) }; #[cfg(not(feature = "accounts_cache"))] @@ -274,8 +272,7 @@ impl MerchantConnectorAccountInterface for Store { connector_name, ) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) .async_and_then(|items| async { let mut output = Vec::with_capacity(items.len()); for item in items.into_iter() { @@ -305,8 +302,7 @@ impl MerchantConnectorAccountInterface for Store { merchant_connector_id, ) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) }; #[cfg(not(feature = "accounts_cache"))] @@ -345,8 +341,7 @@ impl MerchantConnectorAccountInterface for Store { .change_context(errors::StorageError::EncryptionError)? .insert(&conn) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) .async_and_then(|item| async { item.convert(key_store.key.get_inner()) .await @@ -365,8 +360,7 @@ impl MerchantConnectorAccountInterface for Store { let conn = connection::pg_connection_read(self).await?; storage::MerchantConnectorAccount::find_by_merchant_id(&conn, merchant_id, get_disabled) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) .async_and_then(|items| async { let mut output = Vec::with_capacity(items.len()); for item in items.into_iter() { @@ -406,8 +400,7 @@ impl MerchantConnectorAccountInterface for Store { .change_context(errors::StorageError::EncryptionError)? .update(&conn, merchant_connector_account) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) .async_and_then(|item| async { item.convert(key_store.key.get_inner()) .await @@ -454,8 +447,7 @@ impl MerchantConnectorAccountInterface for Store { merchant_connector_id, ) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) }; #[cfg(feature = "accounts_cache")] @@ -471,8 +463,7 @@ impl MerchantConnectorAccountInterface for Store { merchant_connector_id, ) .await - .map_err(Into::into) - .into_report()?; + .map_err(|error| report!(errors::StorageError::from(error)))?; let _profile_id = mca.profile_id.ok_or(errors::StorageError::ValueNotFound( "profile_id".to_string(), @@ -628,11 +619,7 @@ impl MerchantConnectorAccountInterface for MockDb { ) -> CustomResult { let mut accounts = self.merchant_connector_accounts.lock().await; let account = storage::MerchantConnectorAccount { - id: accounts - .len() - .try_into() - .into_report() - .change_context(errors::StorageError::MockDbError)?, + id: i32::try_from(accounts.len()).change_context(errors::StorageError::MockDbError)?, merchant_id: t.merchant_id, connector_name: t.connector_name, connector_account_details: t.connector_account_details.into(), diff --git a/crates/router/src/db/merchant_key_store.rs b/crates/router/src/db/merchant_key_store.rs index e3d81302cb9..f857ab9d61e 100644 --- a/crates/router/src/db/merchant_key_store.rs +++ b/crates/router/src/db/merchant_key_store.rs @@ -1,4 +1,4 @@ -use error_stack::{IntoReport, ResultExt}; +use error_stack::{report, ResultExt}; use masking::Secret; use router_env::{instrument, tracing}; #[cfg(feature = "accounts_cache")] @@ -57,8 +57,7 @@ impl MerchantKeyStoreInterface for Store { .change_context(errors::StorageError::EncryptionError)? .insert(&conn) .await - .map_err(Into::into) - .into_report()? + .map_err(|error| report!(errors::StorageError::from(error)))? .convert(key) .await .change_context(errors::StorageError::DecryptionError) @@ -78,8 +77,7 @@ impl MerchantKeyStoreInterface for Store { merchant_id, ) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) }; #[cfg(not(feature = "accounts_cache"))] @@ -119,8 +117,7 @@ impl MerchantKeyStoreInterface for Store { merchant_id, ) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) }; #[cfg(not(feature = "accounts_cache"))] @@ -155,8 +152,7 @@ impl MerchantKeyStoreInterface for Store { merchant_ids, ) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) }; futures::future::try_join_all(fetch_func().await?.into_iter().map(|key_store| async { diff --git a/crates/router/src/db/organization.rs b/crates/router/src/db/organization.rs index 63e4a0e8cd3..0fe9ea9a180 100644 --- a/crates/router/src/db/organization.rs +++ b/crates/router/src/db/organization.rs @@ -1,6 +1,6 @@ use common_utils::errors::CustomResult; use diesel_models::organization as storage; -use error_stack::IntoReport; +use error_stack::report; use router_env::{instrument, tracing}; use crate::{connection, core::errors, services::Store}; @@ -35,8 +35,7 @@ impl OrganizationInterface for Store { organization .insert(&conn) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } #[instrument(skip_all)] @@ -47,8 +46,7 @@ impl OrganizationInterface for Store { let conn = connection::pg_connection_read(self).await?; storage::Organization::find_by_org_id(&conn, org_id.to_string()) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } #[instrument(skip_all)] @@ -61,8 +59,7 @@ impl OrganizationInterface for Store { storage::Organization::update_by_org_id(&conn, org_id.to_string(), update) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } } diff --git a/crates/router/src/db/payment_link.rs b/crates/router/src/db/payment_link.rs index 1a85de9e882..c3f78767931 100644 --- a/crates/router/src/db/payment_link.rs +++ b/crates/router/src/db/payment_link.rs @@ -1,4 +1,4 @@ -use error_stack::IntoReport; +use error_stack::report; use router_env::{instrument, tracing}; use crate::{ @@ -38,8 +38,7 @@ impl PaymentLinkInterface for Store { let conn = connection::pg_connection_read(self).await?; storage::PaymentLink::find_link_by_payment_link_id(&conn, payment_link_id) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } #[instrument(skip_all)] @@ -51,8 +50,7 @@ impl PaymentLinkInterface for Store { payment_link_config .insert(&conn) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } #[instrument(skip_all)] @@ -64,8 +62,7 @@ impl PaymentLinkInterface for Store { let conn = connection::pg_connection_read(self).await?; storage::PaymentLink::filter_by_constraints(&conn, merchant_id, payment_link_constraints) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } } diff --git a/crates/router/src/db/payment_method.rs b/crates/router/src/db/payment_method.rs index 94ebee17893..14f650127dd 100644 --- a/crates/router/src/db/payment_method.rs +++ b/crates/router/src/db/payment_method.rs @@ -1,5 +1,5 @@ use diesel_models::payment_method::PaymentMethodUpdateInternal; -use error_stack::{IntoReport, ResultExt}; +use error_stack::{report, ResultExt}; use router_env::{instrument, tracing}; use super::{MockDb, Store}; @@ -71,8 +71,7 @@ impl PaymentMethodInterface for Store { let conn = connection::pg_connection_read(self).await?; storage::PaymentMethod::find_by_payment_method_id(&conn, payment_method_id) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } #[instrument(skip_all)] @@ -83,8 +82,7 @@ impl PaymentMethodInterface for Store { let conn = connection::pg_connection_read(self).await?; storage::PaymentMethod::find_by_locker_id(&conn, locker_id) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } #[instrument(skip_all)] @@ -102,8 +100,7 @@ impl PaymentMethodInterface for Store { status, ) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } #[instrument(skip_all)] @@ -115,8 +112,7 @@ impl PaymentMethodInterface for Store { payment_method_new .insert(&conn) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } #[instrument(skip_all)] @@ -129,8 +125,7 @@ impl PaymentMethodInterface for Store { payment_method .update_with_payment_method_id(&conn, payment_method_update) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } #[instrument(skip_all)] @@ -148,8 +143,7 @@ impl PaymentMethodInterface for Store { limit, ) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } #[instrument(skip_all)] @@ -169,8 +163,7 @@ impl PaymentMethodInterface for Store { limit, ) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } async fn delete_payment_method_by_merchant_id_payment_method_id( @@ -185,8 +178,7 @@ impl PaymentMethodInterface for Store { payment_method_id, ) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } } @@ -245,10 +237,7 @@ impl PaymentMethodInterface for MockDb { && pm.status == status }) .count(); - count - .try_into() - .into_report() - .change_context(errors::StorageError::MockDbError) + i64::try_from(count).change_context(errors::StorageError::MockDbError) } async fn insert_payment_method( @@ -258,10 +247,7 @@ impl PaymentMethodInterface for MockDb { let mut payment_methods = self.payment_methods.lock().await; let payment_method = storage::PaymentMethod { - id: payment_methods - .len() - .try_into() - .into_report() + id: i32::try_from(payment_methods.len()) .change_context(errors::StorageError::MockDbError)?, customer_id: payment_method_new.customer_id, merchant_id: payment_method_new.merchant_id, @@ -336,10 +322,10 @@ impl PaymentMethodInterface for MockDb { .collect(); if payment_methods_found.is_empty() { - Err(errors::StorageError::ValueNotFound( - "cannot find payment methods".to_string(), - )) - .into_report() + Err( + errors::StorageError::ValueNotFound("cannot find payment methods".to_string()) + .into(), + ) } else { Ok(payment_methods_found) } diff --git a/crates/router/src/db/refund.rs b/crates/router/src/db/refund.rs index cc2d7e8b7b9..c62f8469515 100644 --- a/crates/router/src/db/refund.rs +++ b/crates/router/src/db/refund.rs @@ -2,7 +2,7 @@ use std::collections::HashSet; use diesel_models::{errors::DatabaseError, refund::RefundUpdateInternal}; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use super::MockDb; use crate::{ @@ -93,7 +93,7 @@ pub trait RefundInterface { #[cfg(not(feature = "kv_store"))] mod storage { - use error_stack::IntoReport; + use error_stack::report; use router_env::{instrument, tracing}; use super::RefundInterface; @@ -120,8 +120,7 @@ mod storage { merchant_id, ) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } #[instrument(skip_all)] @@ -131,7 +130,9 @@ mod storage { _storage_scheme: enums::MerchantStorageScheme, ) -> CustomResult { let conn = connection::pg_connection_write(self).await?; - new.insert(&conn).await.map_err(Into::into).into_report() + new.insert(&conn) + .await + .map_err(|error| report!(errors::StorageError::from(error))) } #[instrument(skip_all)] @@ -148,8 +149,7 @@ mod storage { connector_transaction_id, ) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } #[instrument(skip_all)] @@ -162,8 +162,7 @@ mod storage { let conn = connection::pg_connection_write(self).await?; this.update(&conn, refund) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } #[instrument(skip_all)] @@ -176,8 +175,7 @@ mod storage { let conn = connection::pg_connection_read(self).await?; storage_types::Refund::find_by_merchant_id_refund_id(&conn, merchant_id, refund_id) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } #[instrument(skip_all)] @@ -196,8 +194,7 @@ mod storage { connector, ) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } #[instrument(skip_all)] @@ -210,8 +207,7 @@ mod storage { let conn = connection::pg_connection_read(self).await?; storage_types::Refund::find_by_payment_id_merchant_id(&conn, payment_id, merchant_id) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } #[cfg(feature = "olap")] @@ -233,8 +229,7 @@ mod storage { offset, ) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } #[cfg(feature = "olap")] @@ -252,8 +247,7 @@ mod storage { refund_details, ) .await - .map_err(Into::into) - .into_report() + .map_err(|error|report!(errors::StorageError::from(error))) } #[cfg(feature = "olap")] #[instrument(skip_all)] @@ -270,8 +264,7 @@ mod storage { refund_details, ) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } } } @@ -279,7 +272,7 @@ mod storage { #[cfg(feature = "kv_store")] mod storage { use common_utils::{date_time, ext_traits::Encode, fallback_reverse_lookup_not_found}; - use error_stack::{IntoReport, ResultExt}; + use error_stack::{report, ResultExt}; use redis_interface::HsetnxReply; use router_env::{instrument, tracing}; use storage_impl::redis::kv_store::{kv_wrapper, KvOperation}; @@ -310,8 +303,7 @@ mod storage { merchant_id, ) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) }; match storage_scheme { enums::MerchantStorageScheme::PostgresOnly => database_call().await, @@ -350,7 +342,9 @@ mod storage { match storage_scheme { enums::MerchantStorageScheme::PostgresOnly => { let conn = connection::pg_connection_write(self).await?; - new.insert(&conn).await.map_err(Into::into).into_report() + new.insert(&conn) + .await + .map_err(|error| report!(errors::StorageError::from(error))) } enums::MerchantStorageScheme::RedisKv => { let key = format!("mid_{}_pid_{}", new.merchant_id, new.payment_id); @@ -457,8 +451,8 @@ mod storage { Ok(HsetnxReply::KeyNotSet) => Err(errors::StorageError::DuplicateValue { entity: "refund", key: Some(created_refund.refund_id), - }) - .into_report(), + } + .into()), Ok(HsetnxReply::KeySet) => Ok(created_refund), Err(er) => Err(er).change_context(errors::StorageError::KVError), } @@ -481,8 +475,7 @@ mod storage { connector_transaction_id, ) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) }; match storage_scheme { enums::MerchantStorageScheme::PostgresOnly => database_call().await, @@ -528,8 +521,7 @@ mod storage { let conn = connection::pg_connection_write(self).await?; this.update(&conn, refund) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } enums::MerchantStorageScheme::RedisKv => { let key = format!("mid_{}_pid_{}", this.merchant_id, this.payment_id); @@ -578,8 +570,7 @@ mod storage { let conn = connection::pg_connection_read(self).await?; storage_types::Refund::find_by_merchant_id_refund_id(&conn, merchant_id, refund_id) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) }; match storage_scheme { enums::MerchantStorageScheme::PostgresOnly => database_call().await, @@ -626,8 +617,7 @@ mod storage { connector, ) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) }; match storage_scheme { enums::MerchantStorageScheme::PostgresOnly => database_call().await, @@ -673,8 +663,7 @@ mod storage { merchant_id, ) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) }; match storage_scheme { enums::MerchantStorageScheme::PostgresOnly => database_call().await, @@ -716,8 +705,7 @@ mod storage { offset, ) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } #[cfg(feature = "olap")] @@ -731,8 +719,7 @@ mod storage { let conn = connection::pg_connection_read(self).await?; ::filter_by_meta_constraints(&conn, merchant_id, refund_details) .await - .map_err(Into::into) - .into_report() + .map_err(|error|report!(errors::StorageError::from(error))) } #[cfg(feature = "olap")] @@ -750,8 +737,7 @@ mod storage { refund_details, ) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } } } @@ -786,11 +772,7 @@ impl RefundInterface for MockDb { let current_time = common_utils::date_time::now(); let refund = storage_types::Refund { - id: refunds - .len() - .try_into() - .into_report() - .change_context(errors::StorageError::MockDbError)?, + id: i32::try_from(refunds.len()).change_context(errors::StorageError::MockDbError)?, internal_reference_id: new.internal_reference_id, refund_id: new.refund_id, payment_id: new.payment_id, diff --git a/crates/router/src/db/reverse_lookup.rs b/crates/router/src/db/reverse_lookup.rs index ccb77571cfd..852d6359c97 100644 --- a/crates/router/src/db/reverse_lookup.rs +++ b/crates/router/src/db/reverse_lookup.rs @@ -23,7 +23,7 @@ pub trait ReverseLookupInterface { #[cfg(not(feature = "kv_store"))] mod storage { - use error_stack::IntoReport; + use error_stack::report; use router_env::{instrument, tracing}; use super::{ReverseLookupInterface, Store}; @@ -45,7 +45,9 @@ mod storage { _storage_scheme: enums::MerchantStorageScheme, ) -> CustomResult { let conn = connection::pg_connection_write(self).await?; - new.insert(&conn).await.map_err(Into::into).into_report() + new.insert(&conn) + .await + .map_err(|error| report!(errors::StorageError::from(error))) } #[instrument(skip_all)] @@ -57,15 +59,14 @@ mod storage { let conn = connection::pg_connection_read(self).await?; ReverseLookup::find_by_lookup_id(id, &conn) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } } } #[cfg(feature = "kv_store")] mod storage { - use error_stack::{IntoReport, ResultExt}; + use error_stack::{report, ResultExt}; use redis_interface::SetnxReply; use router_env::{instrument, tracing}; use storage_impl::redis::kv_store::{kv_wrapper, KvOperation}; @@ -93,7 +94,9 @@ mod storage { match storage_scheme { enums::MerchantStorageScheme::PostgresOnly => { let conn = connection::pg_connection_write(self).await?; - new.insert(&conn).await.map_err(Into::into).into_report() + new.insert(&conn) + .await + .map_err(|error| report!(errors::StorageError::from(error))) } enums::MerchantStorageScheme::RedisKv => { let created_rev_lookup = ReverseLookup { @@ -122,8 +125,8 @@ mod storage { Ok(SetnxReply::KeyNotSet) => Err(errors::StorageError::DuplicateValue { entity: "reverse_lookup", key: Some(created_rev_lookup.lookup_id.clone()), - }) - .into_report(), + } + .into()), Err(er) => Err(er).change_context(errors::StorageError::KVError), } } @@ -140,8 +143,7 @@ mod storage { let conn = connection::pg_connection_read(self).await?; ReverseLookup::find_by_lookup_id(id, &conn) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) }; match storage_scheme { diff --git a/crates/router/src/db/role.rs b/crates/router/src/db/role.rs index c8777e3112c..54b7f6e38d4 100644 --- a/crates/router/src/db/role.rs +++ b/crates/router/src/db/role.rs @@ -1,6 +1,6 @@ use common_enums::enums; use diesel_models::role as storage; -use error_stack::{IntoReport, ResultExt}; +use error_stack::{report, ResultExt}; use router_env::{instrument, tracing}; use super::MockDb; @@ -55,7 +55,9 @@ impl RoleInterface for Store { role: storage::RoleNew, ) -> CustomResult { let conn = connection::pg_connection_write(self).await?; - role.insert(&conn).await.map_err(Into::into).into_report() + role.insert(&conn) + .await + .map_err(|error| report!(errors::StorageError::from(error))) } #[instrument(skip_all)] @@ -66,8 +68,7 @@ impl RoleInterface for Store { let conn = connection::pg_connection_write(self).await?; storage::Role::find_by_role_id(&conn, role_id) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } #[instrument(skip_all)] @@ -80,8 +81,7 @@ impl RoleInterface for Store { let conn = connection::pg_connection_write(self).await?; storage::Role::find_by_role_id_in_merchant_scope(&conn, role_id, merchant_id, org_id) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } #[instrument(skip_all)] @@ -93,8 +93,7 @@ impl RoleInterface for Store { let conn = connection::pg_connection_write(self).await?; storage::Role::update_by_role_id(&conn, role_id, role_update) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } #[instrument(skip_all)] @@ -105,8 +104,7 @@ impl RoleInterface for Store { let conn = connection::pg_connection_write(self).await?; storage::Role::delete_by_role_id(&conn, role_id) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } #[instrument(skip_all)] @@ -118,8 +116,7 @@ impl RoleInterface for Store { let conn = connection::pg_connection_write(self).await?; storage::Role::list_roles(&conn, merchant_id, org_id) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } } @@ -140,11 +137,7 @@ impl RoleInterface for MockDb { })? } let role = storage::Role { - id: roles - .len() - .try_into() - .into_report() - .change_context(errors::StorageError::MockDbError)?, + id: i32::try_from(roles.len()).change_context(errors::StorageError::MockDbError)?, role_name: role.role_name, role_id: role.role_id, merchant_id: role.merchant_id, diff --git a/crates/router/src/db/routing_algorithm.rs b/crates/router/src/db/routing_algorithm.rs index e0f74358b97..f65933d8982 100644 --- a/crates/router/src/db/routing_algorithm.rs +++ b/crates/router/src/db/routing_algorithm.rs @@ -1,5 +1,5 @@ use diesel_models::routing_algorithm as routing_storage; -use error_stack::IntoReport; +use error_stack::report; use router_env::{instrument, tracing}; use storage_impl::mock_db::MockDb; @@ -70,8 +70,7 @@ impl RoutingAlgorithmInterface for Store { routing_algorithm .insert(&conn) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } #[instrument(skip_all)] @@ -87,8 +86,7 @@ impl RoutingAlgorithmInterface for Store { profile_id, ) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } #[instrument(skip_all)] @@ -104,8 +102,7 @@ impl RoutingAlgorithmInterface for Store { merchant_id, ) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } #[instrument(skip_all)] @@ -121,8 +118,7 @@ impl RoutingAlgorithmInterface for Store { profile_id, ) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } #[instrument(skip_all)] @@ -137,8 +133,7 @@ impl RoutingAlgorithmInterface for Store { &conn, profile_id, limit, offset, ) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } #[instrument(skip_all)] @@ -156,8 +151,7 @@ impl RoutingAlgorithmInterface for Store { offset, ) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } async fn list_routing_algorithm_metadata_by_merchant_id_transaction_type( @@ -176,8 +170,7 @@ impl RoutingAlgorithmInterface for Store { offset, ) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } } diff --git a/crates/router/src/db/user.rs b/crates/router/src/db/user.rs index 6148e67b294..a96829a756e 100644 --- a/crates/router/src/db/user.rs +++ b/crates/router/src/db/user.rs @@ -1,5 +1,5 @@ use diesel_models::{user as storage, user_role::UserRole}; -use error_stack::{IntoReport, ResultExt}; +use error_stack::{report, ResultExt}; use masking::Secret; use router_env::{instrument, tracing}; @@ -62,8 +62,7 @@ impl UserInterface for Store { user_data .insert(&conn) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } #[instrument(skip_all)] @@ -74,8 +73,7 @@ impl UserInterface for Store { let conn = connection::pg_connection_write(self).await?; storage::User::find_by_user_email(&conn, user_email) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } #[instrument(skip_all)] @@ -86,8 +84,7 @@ impl UserInterface for Store { let conn = connection::pg_connection_write(self).await?; storage::User::find_by_user_id(&conn, user_id) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } #[instrument(skip_all)] @@ -99,8 +96,7 @@ impl UserInterface for Store { let conn = connection::pg_connection_write(self).await?; storage::User::update_by_user_id(&conn, user_id, user) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } #[instrument(skip_all)] @@ -112,8 +108,7 @@ impl UserInterface for Store { let conn = connection::pg_connection_write(self).await?; storage::User::update_by_user_email(&conn, user_email, user) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } #[instrument(skip_all)] @@ -124,8 +119,7 @@ impl UserInterface for Store { let conn = connection::pg_connection_write(self).await?; storage::User::delete_by_user_id(&conn, user_id) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } #[instrument(skip_all)] @@ -136,8 +130,7 @@ impl UserInterface for Store { let conn = connection::pg_connection_write(self).await?; storage::User::find_joined_users_and_roles_by_merchant_id(&conn, merchant_id) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } } @@ -159,11 +152,7 @@ impl UserInterface for MockDb { } let time_now = common_utils::date_time::now(); let user = storage::User { - id: users - .len() - .try_into() - .into_report() - .change_context(errors::StorageError::MockDbError)?, + id: i32::try_from(users.len()).change_context(errors::StorageError::MockDbError)?, user_id: user_data.user_id, email: user_data.email, name: user_data.name, diff --git a/crates/router/src/db/user_role.rs b/crates/router/src/db/user_role.rs index ae2c85db041..2f61f70b2a8 100644 --- a/crates/router/src/db/user_role.rs +++ b/crates/router/src/db/user_role.rs @@ -2,7 +2,7 @@ use std::{collections::HashSet, ops::Not}; use async_bb8_diesel::AsyncConnection; use diesel_models::{enums, user_role as storage}; -use error_stack::{IntoReport, ResultExt}; +use error_stack::{report, ResultExt}; use router_env::{instrument, tracing}; use super::MockDb; @@ -74,8 +74,7 @@ impl UserRoleInterface for Store { user_role .insert(&conn) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } #[instrument(skip_all)] @@ -86,8 +85,7 @@ impl UserRoleInterface for Store { let conn = connection::pg_connection_write(self).await?; storage::UserRole::find_by_user_id(&conn, user_id.to_owned()) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } #[instrument(skip_all)] @@ -103,8 +101,7 @@ impl UserRoleInterface for Store { merchant_id.to_owned(), ) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } #[instrument(skip_all)] @@ -122,8 +119,7 @@ impl UserRoleInterface for Store { update, ) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } #[instrument(skip_all)] @@ -141,8 +137,7 @@ impl UserRoleInterface for Store { update, ) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } #[instrument(skip_all)] @@ -158,8 +153,7 @@ impl UserRoleInterface for Store { merchant_id.to_owned(), ) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } #[instrument(skip_all)] @@ -170,8 +164,7 @@ impl UserRoleInterface for Store { let conn = connection::pg_connection_write(self).await?; storage::UserRole::list_by_user_id(&conn, user_id.to_owned()) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } #[instrument(skip_all)] @@ -248,9 +241,7 @@ impl UserRoleInterface for Store { Ok::<_, errors::DatabaseError>(()) }) .await - .into_report() - .map_err(Into::into) - .into_report()?; + .map_err(|error| report!(errors::StorageError::from(report!(error))))?; Ok(()) } @@ -273,10 +264,7 @@ impl UserRoleInterface for MockDb { })? } let user_role = storage::UserRole { - id: user_roles - .len() - .try_into() - .into_report() + id: i32::try_from(user_roles.len()) .change_context(errors::StorageError::MockDbError)?, user_id: user_role.user_id, merchant_id: user_role.merchant_id, diff --git a/crates/router/src/routes/disputes/utils.rs b/crates/router/src/routes/disputes/utils.rs index 33000bbd98d..9ad5a55c9c8 100644 --- a/crates/router/src/routes/disputes/utils.rs +++ b/crates/router/src/routes/disputes/utils.rs @@ -1,7 +1,7 @@ use actix_multipart::{Field, Multipart}; use actix_web::web::Bytes; use common_utils::{errors::CustomResult, ext_traits::StringExt, fp_utils}; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use futures::{StreamExt, TryStreamExt}; use crate::{ @@ -48,7 +48,6 @@ pub async fn get_attach_evidence_request( match chunk { Ok(bytes) => file_data.push(bytes), Err(err) => Err(errors::ApiErrorResponse::InternalServerError) - .into_report() .attach_printable_lazy(|| format!("File parsing error: {err}"))?, } } @@ -67,16 +66,12 @@ pub async fn get_attach_evidence_request( let evidence_type = option_evidence_type.get_required_value("evidence_type")?; let file = file_content.get_required_value("file")?.concat().to_vec(); //Get and validate file size - let file_size: i32 = file - .len() - .try_into() - .into_report() + let file_size = i32::try_from(file.len()) .change_context(errors::ApiErrorResponse::InternalServerError) .attach_printable("File size error")?; // Check if empty file and throw error fp_utils::when(file_size <= 0, || { Err(errors::ApiErrorResponse::MissingFile) - .into_report() .attach_printable("Missing / Invalid file in the request") })?; // Get file mime type using 'infer' @@ -84,7 +79,6 @@ pub async fn get_attach_evidence_request( let file_type = kind .mime_type() .parse::() - .into_report() .change_context(errors::ApiErrorResponse::MissingFileContentType) .attach_printable("File content type error")?; let create_file_request = files::CreateFileRequest { diff --git a/crates/router/src/routes/dummy_connector/utils.rs b/crates/router/src/routes/dummy_connector/utils.rs index 1bf13df599c..8bba182ad0a 100644 --- a/crates/router/src/routes/dummy_connector/utils.rs +++ b/crates/router/src/routes/dummy_connector/utils.rs @@ -1,7 +1,7 @@ use std::fmt::Debug; use common_utils::ext_traits::AsyncExt; -use error_stack::{report, IntoReport, ResultExt}; +use error_stack::{report, ResultExt}; use masking::PeekInterface; use maud::html; use rand::{distributions::Uniform, prelude::Distribution}; @@ -222,7 +222,7 @@ impl ProcessPaymentAttempt for types::DummyConnectorCard { match self.get_flow_from_card_number()? { types::DummyConnectorCardFlow::NoThreeDS(status, error) => { if let Some(error) = error { - Err(error).into_report()?; + Err(error)?; } Ok(payment_attempt.build_payment_data(status, None, None)) } diff --git a/crates/router/src/routes/files/transformers.rs b/crates/router/src/routes/files/transformers.rs index c49f6892b57..7feb73353bc 100644 --- a/crates/router/src/routes/files/transformers.rs +++ b/crates/router/src/routes/files/transformers.rs @@ -1,7 +1,7 @@ use actix_multipart::Multipart; use actix_web::web::Bytes; use common_utils::errors::CustomResult; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use futures::{StreamExt, TryStreamExt}; use crate::{ @@ -37,7 +37,6 @@ pub async fn get_create_file_request( match chunk { Ok(bytes) => file_data.push(bytes), Err(err) => Err(errors::ApiErrorResponse::InternalServerError) - .into_report() .attach_printable(format!("{}{}", "File parsing error: ", err))?, } } @@ -54,20 +53,15 @@ pub async fn get_create_file_request( let file = match file_content { Some(valid_file_content) => valid_file_content.concat().to_vec(), None => Err(errors::ApiErrorResponse::MissingFile) - .into_report() .attach_printable("Missing / Invalid file in the request")?, }; //Get and validate file size - let file_size: i32 = file - .len() - .try_into() - .into_report() + let file_size = i32::try_from(file.len()) .change_context(errors::ApiErrorResponse::InternalServerError) .attach_printable("File size error")?; // Check if empty file and throw error if file_size <= 0 { Err(errors::ApiErrorResponse::MissingFile) - .into_report() .attach_printable("Missing / Invalid file in the request")? } // Get file mime type using 'infer' @@ -75,7 +69,6 @@ pub async fn get_create_file_request( let file_type = kind .mime_type() .parse::() - .into_report() .change_context(errors::ApiErrorResponse::MissingFileContentType) .attach_printable("File content type error")?; Ok(CreateFileRequest { diff --git a/crates/router/src/routes/payments.rs b/crates/router/src/routes/payments.rs index 73d891c8984..eda181f5a8b 100644 --- a/crates/router/src/routes/payments.rs +++ b/crates/router/src/routes/payments.rs @@ -6,7 +6,7 @@ pub mod helpers; use actix_web::{web, Responder}; use api_models::payments::HeaderPayload; -use error_stack::{report, IntoReport}; +use error_stack::report; use router_env::{env, instrument, tracing, types, Flow}; use crate::{ @@ -1332,8 +1332,7 @@ pub fn get_or_generate_payment_id( }) .transpose()?; - let payment_id = - core_utils::get_or_generate_id("payment_id", &given_payment_id, "pay").into_report()?; + let payment_id = core_utils::get_or_generate_id("payment_id", &given_payment_id, "pay")?; payload.payment_id = Some(api_models::payments::PaymentIdType::PaymentIntentId( payment_id, diff --git a/crates/router/src/routes/recon.rs b/crates/router/src/routes/recon.rs index 22c886e1358..faa41d9d1d2 100644 --- a/crates/router/src/routes/recon.rs +++ b/crates/router/src/routes/recon.rs @@ -209,11 +209,11 @@ pub async fn recon_merchant_account_update( } Ok(service_api::ApplicationResponse::Json( - response - .try_into() - .change_context(errors::ApiErrorResponse::InvalidDataValue { + api_types::MerchantAccountResponse::try_from(response).change_context( + errors::ApiErrorResponse::InvalidDataValue { field_name: "merchant_account", - })?, + }, + )?, )) } diff --git a/crates/router/src/services.rs b/crates/router/src/services.rs index 617b9df7122..6b604498c71 100644 --- a/crates/router/src/services.rs +++ b/crates/router/src/services.rs @@ -14,7 +14,7 @@ pub mod recon; pub mod email; use data_models::errors::StorageResult; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use masking::{ExposeInterface, StrongSecret}; #[cfg(feature = "kv_store")] use storage_impl::KVRouterStore; @@ -91,7 +91,6 @@ pub fn generate_aes256_key() -> errors::CustomResult<[u8; 32], common_utils::err let rng = ring::rand::SystemRandom::new(); let mut key: [u8; 256 / 8] = [0_u8; 256 / 8]; rng.fill(&mut key) - .into_report() .change_context(common_utils::errors::CryptoError::EncodingFailed)?; Ok(key) } diff --git a/crates/router/src/services/api.rs b/crates/router/src/services/api.rs index 40a9713a8cf..95eb4a44c8a 100644 --- a/crates/router/src/services/api.rs +++ b/crates/router/src/services/api.rs @@ -22,7 +22,7 @@ use common_utils::{ errors::{ErrorSwitch, ReportSwitchExt}, request::RequestContent, }; -use error_stack::{report, IntoReport, Report, ResultExt}; +use error_stack::{report, Report, ResultExt}; use masking::{Maskable, PeekInterface, Secret}; use router_env::{instrument, tracing, tracing_actix_web::RequestId, Tag}; use serde::Serialize; @@ -579,7 +579,6 @@ pub async fn send_request( logger::info!(method=?request.method, headers=?request.headers, payload=?request.body, ?request); let url = reqwest::Url::parse(&request.url) - .into_report() .change_context(errors::ApiClientError::UrlEncodingFailed)?; #[cfg(feature = "dummy_connector")] @@ -612,7 +611,6 @@ pub async fn send_request( Some(RequestContent::FormUrlEncoded(payload)) => client.form(&payload), Some(RequestContent::Xml(payload)) => { let body = quick_xml::se::to_string(&payload) - .into_report() .change_context(errors::ApiClientError::BodySerializationFailed)?; client.body(body).header("Content-Type", "application/xml") } @@ -628,7 +626,6 @@ pub async fn send_request( Some(RequestContent::FormUrlEncoded(payload)) => client.form(&payload), Some(RequestContent::Xml(payload)) => { let body = quick_xml::se::to_string(&payload) - .into_report() .change_context(errors::ApiClientError::BodySerializationFailed)?; client.body(body).header("Content-Type", "application/xml") } @@ -644,7 +641,6 @@ pub async fn send_request( Some(RequestContent::FormUrlEncoded(payload)) => client.form(&payload), Some(RequestContent::Xml(payload)) => { let body = quick_xml::se::to_string(&payload) - .into_report() .change_context(errors::ApiClientError::BodySerializationFailed)?; client.body(body).header("Content-Type", "application/xml") } @@ -676,7 +672,6 @@ pub async fn send_request( } _ => errors::ApiClientError::RequestNotSent(error.to_string()), }) - .into_report() .attach_printable("Unable to send request to connector") }); @@ -695,7 +690,6 @@ pub async fn send_request( } _ => errors::ApiClientError::RequestNotSent(error.to_string()), }) - .into_report() .attach_printable("Unable to send request to connector") }; @@ -774,7 +768,6 @@ async fn handle_response( let response = response .bytes() .await - .into_report() .change_context(errors::ApiClientError::ResponseDecodingFailed) .attach_printable("Error while waiting for response")?; Ok(Ok(types::Response { @@ -972,7 +965,6 @@ where { let request_id = RequestId::extract(request) .await - .into_report() .attach_printable("Unable to extract request id from request") .change_context(errors::ApiErrorResponse::InternalServerError.switch())?; @@ -981,7 +973,6 @@ where request_state.add_request_id(request_id); let start_instant = Instant::now(); let serialized_request = masking::masked_serialize(&payload) - .into_report() .attach_printable("Failed to serialize json request") .change_context(errors::ApiErrorResponse::InternalServerError.switch())?; @@ -1032,14 +1023,12 @@ where if let ApplicationResponse::Json(data) = res { serialized_response.replace( masking::masked_serialize(&data) - .into_report() .attach_printable("Failed to serialize json response") .change_context(errors::ApiErrorResponse::InternalServerError.switch())?, ); } else if let ApplicationResponse::JsonWithHeaders((data, headers)) = res { serialized_response.replace( masking::masked_serialize(&data) - .into_report() .attach_printable("Failed to serialize json response") .change_context(errors::ApiErrorResponse::InternalServerError.switch())?, ); @@ -1057,7 +1046,6 @@ where Err(err) => { error.replace( serde_json::to_value(err.current_context()) - .into_report() .attach_printable("Failed to serialize json response") .change_context(errors::ApiErrorResponse::InternalServerError.switch()) .ok() @@ -1499,7 +1487,6 @@ pub fn build_redirection_form( "#)) - h3 style="text-align: center;" { "Please wait while we process your payment..." } form action=(PreEscaped(endpoint)) method=(method.to_string()) #payment_form { @for (field, value) in form_fields { @@ -1557,7 +1544,6 @@ pub fn build_redirection_form( "#)) - h3 style="text-align: center;" { "Please wait while we process your payment..." } } @@ -1613,7 +1599,6 @@ pub fn build_redirection_form( "#)) - h3 style="text-align: center;" { "Please wait while we process your payment..." } } @@ -1666,7 +1651,6 @@ pub fn build_redirection_form( "#)) - h3 style="text-align: center;" { "Please wait while we process your payment..." } } @@ -1745,7 +1729,6 @@ pub fn build_redirection_form( "#)) - h3 style="text-align: center;" { "Please wait while we process your payment..." } } diff --git a/crates/router/src/services/api/client.rs b/crates/router/src/services/api/client.rs index a2cf65ce66b..816269c086f 100644 --- a/crates/router/src/services/api/client.rs +++ b/crates/router/src/services/api/client.rs @@ -1,6 +1,6 @@ use std::time::Duration; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use http::{HeaderValue, Method}; use masking::PeekInterface; use once_cell::sync::OnceCell; @@ -41,7 +41,6 @@ fn get_client_builder( if let Some(url) = proxy_config.https_url.as_ref() { client_builder = client_builder.proxy( reqwest::Proxy::https(url) - .into_report() .change_context(ApiClientError::InvalidProxyConfiguration) .attach_printable("HTTPS proxy configuration error")?, ); @@ -51,7 +50,6 @@ fn get_client_builder( if let Some(url) = proxy_config.http_url.as_ref() { client_builder = client_builder.proxy( reqwest::Proxy::http(url) - .into_report() .change_context(ApiClientError::InvalidProxyConfiguration) .attach_printable("HTTP proxy configuration error")?, ); @@ -74,7 +72,6 @@ fn get_base_client( .get_or_try_init(|| { get_client_builder(proxy_config, should_bypass_proxy)? .build() - .into_report() .change_context(ApiClientError::ClientConstructionFailed) .attach_printable("Failed to construct base client") })? @@ -101,7 +98,6 @@ pub(super) fn create_client( client_builder .identity(identity) .build() - .into_report() .change_context(ApiClientError::ClientConstructionFailed) .attach_printable("Failed to construct client with certificate and certificate key") } @@ -194,7 +190,6 @@ impl ProxyClient { let non_proxy_client = reqwest::Client::builder() .redirect(reqwest::redirect::Policy::none()) .build() - .into_report() .change_context(ApiClientError::ClientConstructionFailed)?; let mut proxy_builder = @@ -203,7 +198,6 @@ impl ProxyClient { if let Some(url) = proxy_config.https_url.as_ref() { proxy_builder = proxy_builder.proxy( reqwest::Proxy::https(url) - .into_report() .change_context(ApiClientError::InvalidProxyConfiguration)?, ); } @@ -211,14 +205,12 @@ impl ProxyClient { if let Some(url) = proxy_config.http_url.as_ref() { proxy_builder = proxy_builder.proxy( reqwest::Proxy::http(url) - .into_report() .change_context(ApiClientError::InvalidProxyConfiguration)?, ); } let proxy_client = proxy_builder .build() - .into_report() .change_context(ApiClientError::InvalidProxyConfiguration)?; Ok(Self { proxy_client, @@ -245,7 +237,6 @@ impl ProxyClient { Ok(client_builder .identity(identity) .build() - .into_report() .change_context(ApiClientError::ClientConstructionFailed) .attach_printable( "Failed to construct client with certificate and certificate key", @@ -295,7 +286,6 @@ impl RequestBuilder for RouterRequestBuilder { }), Maskable::Normal(hvalue) => HeaderValue::from_str(&hvalue), } - .into_report() .change_context(ApiClientError::HeaderMapConstructionFailed)?; self.inner = self.inner.take().map(|r| r.header(key, header_value)); diff --git a/crates/router/src/services/api/request.rs b/crates/router/src/services/api/request.rs index 1f672b0f0de..ed53da0d971 100644 --- a/crates/router/src/services/api/request.rs +++ b/crates/router/src/services/api/request.rs @@ -2,7 +2,7 @@ use std::str::FromStr; pub use common_utils::request::ContentType; use common_utils::request::Headers; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; pub use masking::{Mask, Maskable}; use router_env::{instrument, tracing}; @@ -24,11 +24,9 @@ impl HeaderExt for Headers { HeaderMap::new(), |mut header_map, (header_name, header_value)| { let header_name = HeaderName::from_str(&header_name) - .into_report() .change_context(errors::ApiClientError::HeaderMapConstructionFailed)?; let header_value = header_value.into_inner(); let header_value = HeaderValue::from_str(&header_value) - .into_report() .change_context(errors::ApiClientError::HeaderMapConstructionFailed)?; header_map.append(header_name, header_value); Ok(header_map) diff --git a/crates/router/src/services/authentication.rs b/crates/router/src/services/authentication.rs index ca8378080cf..d2247150d3c 100644 --- a/crates/router/src/services/authentication.rs +++ b/crates/router/src/services/authentication.rs @@ -2,7 +2,7 @@ use actix_web::http::header::HeaderMap; use api_models::{payment_methods::PaymentMethodListRequest, payments}; use async_trait::async_trait; use common_utils::date_time; -use error_stack::{report, IntoReport, ResultExt}; +use error_stack::{report, ResultExt}; use jsonwebtoken::{decode, Algorithm, DecodingKey, Validation}; use masking::PeekInterface; use serde::Serialize; @@ -214,7 +214,6 @@ where .trim(); if api_key.is_empty() { return Err(errors::ApiErrorResponse::Unauthorized) - .into_report() .attach_printable("API key is empty"); } @@ -927,7 +926,6 @@ where let key = DecodingKey::from_secret(secret); decode::(token, &key, &Validation::new(Algorithm::HS256)) .map(|decoded| decoded.claims) - .into_report() .change_context(errors::ApiErrorResponse::InvalidJwtToken) } @@ -941,7 +939,6 @@ pub fn get_header_value_by_key(key: String, headers: &HeaderMap) -> RouterResult .map(|source_str| { source_str .to_str() - .into_report() .change_context(errors::ApiErrorResponse::InternalServerError) .attach_printable(format!( "Failed to convert header value to string for header key: {}", @@ -956,7 +953,6 @@ pub fn get_jwt_from_authorization_header(headers: &HeaderMap) -> RouterResult<&s .get(crate::headers::AUTHORIZATION) .get_required_value(crate::headers::AUTHORIZATION)? .to_str() - .into_report() .change_context(errors::ApiErrorResponse::InternalServerError) .attach_printable("Failed to convert JWT token to string")? .strip_prefix("Bearer ") diff --git a/crates/router/src/services/authentication/blacklist.rs b/crates/router/src/services/authentication/blacklist.rs index 2ee8302be63..7c1cbf27e10 100644 --- a/crates/router/src/services/authentication/blacklist.rs +++ b/crates/router/src/services/authentication/blacklist.rs @@ -2,7 +2,7 @@ use std::sync::Arc; #[cfg(feature = "olap")] use common_utils::date_time; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use redis_interface::RedisConnectionPool; use super::{AuthToken, UserAuthToken}; @@ -131,10 +131,7 @@ fn get_redis_connection(state: &A) -> RouterResult RouterResult { - expiry - .try_into() - .into_report() - .change_context(ApiErrorResponse::InternalServerError) + i64::try_from(expiry).change_context(ApiErrorResponse::InternalServerError) } #[async_trait::async_trait] diff --git a/crates/router/src/services/authorization.rs b/crates/router/src/services/authorization.rs index dc6d82d4e92..33edb173255 100644 --- a/crates/router/src/services/authorization.rs +++ b/crates/router/src/services/authorization.rs @@ -1,7 +1,7 @@ use std::sync::Arc; use common_enums::PermissionGroup; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use redis_interface::RedisConnectionPool; use router_env::logger; @@ -39,11 +39,8 @@ where let permissions = get_permissions_from_db(state, &token.role_id, &token.merchant_id, &token.org_id).await?; - let token_expiry: i64 = token - .exp - .try_into() - .into_report() - .change_context(ApiErrorResponse::InternalServerError)?; + let token_expiry = + i64::try_from(token.exp).change_context(ApiErrorResponse::InternalServerError)?; let cache_ttl = token_expiry - common_utils::date_time::now_unix_timestamp(); set_permissions_in_cache(state, &token.role_id, &permissions, cache_ttl) diff --git a/crates/router/src/services/encryption.rs b/crates/router/src/services/encryption.rs index 9a8a5f4af4a..dc7e5db079a 100644 --- a/crates/router/src/services/encryption.rs +++ b/crates/router/src/services/encryption.rs @@ -1,6 +1,6 @@ use std::str; -use error_stack::{report, IntoReport, ResultExt}; +use error_stack::{report, ResultExt}; use josekit::{jwe, jws}; use serde::{Deserialize, Serialize}; @@ -37,12 +37,10 @@ pub async fn encrypt_jwe( src_header.set_token_type("JWT"); let encrypter = alg .encrypter_from_pem(public_key) - .into_report() .change_context(errors::EncryptionError) .attach_printable("Error getting JweEncryptor")?; jwe::serialize_compact(payload, &src_header, &encrypter) - .into_report() .change_context(errors::EncryptionError) .attach_printable("Error getting jwt string") } @@ -67,17 +65,14 @@ pub async fn decrypt_jwe( let decrypter = alg .decrypter_from_pem(private_key) - .into_report() .change_context(errors::EncryptionError) .attach_printable("Error getting JweDecryptor")?; let (dst_payload, _dst_header) = jwe::deserialize_compact(jwt, &decrypter) - .into_report() .change_context(errors::EncryptionError) .attach_printable("Error getting Decrypted jwe")?; String::from_utf8(dst_payload) - .into_report() .change_context(errors::EncryptionError) .attach_printable("Could not decode JWE payload from UTF-8") } @@ -92,11 +87,9 @@ pub async fn jws_sign_payload( src_header.set_key_id(kid); let signer = alg .signer_from_pem(private_key) - .into_report() .change_context(errors::EncryptionError) .attach_printable("Error getting signer")?; let jwt = jws::serialize_compact(payload, &src_header, &signer) - .into_report() .change_context(errors::EncryptionError) .attach_printable("Error getting signed jwt string")?; Ok(jwt) @@ -110,15 +103,12 @@ pub fn verify_sign( let input = jws_body.as_bytes(); let verifier = alg .verifier_from_pem(key) - .into_report() .change_context(errors::EncryptionError) .attach_printable("Error getting verifier")?; let (dst_payload, _dst_header) = jws::deserialize_compact(input, &verifier) - .into_report() .change_context(errors::EncryptionError) .attach_printable("Error getting Decrypted jws")?; let resp = String::from_utf8(dst_payload) - .into_report() .change_context(errors::EncryptionError) .attach_printable("Could not convert to UTF-8")?; Ok(resp) diff --git a/crates/router/src/services/jwt.rs b/crates/router/src/services/jwt.rs index 6a78e2232a9..aec9ae85e63 100644 --- a/crates/router/src/services/jwt.rs +++ b/crates/router/src/services/jwt.rs @@ -1,5 +1,5 @@ use common_utils::errors::CustomResult; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use jsonwebtoken::{encode, EncodingKey, Header}; use masking::PeekInterface; @@ -12,7 +12,6 @@ pub fn generate_exp( .checked_add(exp_duration) .ok_or(UserErrors::InternalServerError)? .duration_since(std::time::UNIX_EPOCH) - .into_report() .change_context(UserErrors::InternalServerError) } @@ -29,6 +28,5 @@ where claims_data, &EncodingKey::from_secret(jwt_secret.peek().as_bytes()), ) - .into_report() .change_context(UserErrors::InternalServerError) } diff --git a/crates/router/src/services/kafka.rs b/crates/router/src/services/kafka.rs index 77f179a533b..373c268f85b 100644 --- a/crates/router/src/services/kafka.rs +++ b/crates/router/src/services/kafka.rs @@ -1,7 +1,7 @@ use std::sync::Arc; use common_utils::errors::CustomResult; -use error_stack::{report, IntoReport, ResultExt}; +use error_stack::{report, ResultExt}; use rdkafka::{ config::FromClientConfig, producer::{BaseRecord, DefaultProducerContext, Producer, ThreadedProducer}, @@ -31,9 +31,7 @@ where { fn value(&self) -> MQResult> { // Add better error logging here - serde_json::to_vec(&self) - .into_report() - .change_context(KafkaError::GenericError) + serde_json::to_vec(&self).change_context(KafkaError::GenericError) } fn key(&self) -> String; @@ -201,7 +199,6 @@ impl KafkaProducer { ThreadedProducer::from_config( rdkafka::ClientConfig::new().set("bootstrap.servers", conf.brokers.join(",")), ) - .into_report() .change_context(KafkaError::InitializationError)?, )), diff --git a/crates/router/src/types.rs b/crates/router/src/types.rs index 6f73efa832e..4a2a676672c 100644 --- a/crates/router/src/types.rs +++ b/crates/router/src/types.rs @@ -25,7 +25,7 @@ use common_enums::MandateStatus; pub use common_utils::request::RequestContent; use common_utils::{pii, pii::Email}; use data_models::mandates::{CustomerAcceptance, MandateData}; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use masking::Secret; use serde::Serialize; @@ -982,7 +982,6 @@ impl ResponseId { _ => Err(errors::ValidationError::IncorrectValueProvided { field_name: "connector_transaction_id", }) - .into_report() .attach_printable("Expected connector transaction ID not found"), } } diff --git a/crates/router/src/types/api.rs b/crates/router/src/types/api.rs index 95a0989ac2b..4b72c7ac2e6 100644 --- a/crates/router/src/types/api.rs +++ b/crates/router/src/types/api.rs @@ -27,7 +27,7 @@ pub mod webhooks; use std::{fmt::Debug, str::FromStr}; -use error_stack::{report, IntoReport, ResultExt}; +use error_stack::{report, ResultExt}; #[cfg(feature = "frm")] pub use self::fraud_check::*; @@ -280,7 +280,6 @@ impl ConnectorData { ) -> CustomResult { let connector = Self::convert_connector(connectors, name)?; let connector_name = api_enums::Connector::from_str(name) - .into_report() .change_context(errors::ConnectorError::InvalidConnectorName) .change_context(errors::ApiErrorResponse::InternalServerError) .attach_printable_lazy(|| format!("unable to parse connector name {connector:?}"))?; @@ -301,7 +300,6 @@ impl ConnectorData { ) -> CustomResult { let connector = Self::convert_connector(connectors, name)?; let payout_connector_name = api_enums::PayoutConnectors::from_str(name) - .into_report() .change_context(errors::ConnectorError::InvalidConnectorName) .change_context(errors::ApiErrorResponse::InternalServerError) .attach_printable_lazy(|| { diff --git a/crates/router/src/types/api/authentication.rs b/crates/router/src/types/api/authentication.rs index d0c6884450a..b69533db5a2 100644 --- a/crates/router/src/types/api/authentication.rs +++ b/crates/router/src/types/api/authentication.rs @@ -2,7 +2,7 @@ use std::str::FromStr; use api_models::enums; use common_utils::errors::CustomResult; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use super::BoxedConnector; use crate::core::errors; @@ -91,7 +91,6 @@ pub struct AuthenticationConnectorData { impl AuthenticationConnectorData { pub fn get_connector_by_name(name: &str) -> CustomResult { let connector_name = enums::AuthenticationConnectors::from_str(name) - .into_report() .change_context(errors::ApiErrorResponse::IncorrectConnectorNameGiven) .attach_printable_lazy(|| format!("unable to parse connector: {name}"))?; let connector = Self::convert_connector(connector_name)?; diff --git a/crates/router/src/types/api/connector_onboarding/paypal.rs b/crates/router/src/types/api/connector_onboarding/paypal.rs index dbfdd6f5007..22bab6968a8 100644 --- a/crates/router/src/types/api/connector_onboarding/paypal.rs +++ b/crates/router/src/types/api/connector_onboarding/paypal.rs @@ -1,5 +1,5 @@ use api_models::connector_onboarding as api; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use crate::core::errors::{ApiErrorResponse, RouterResult}; @@ -181,7 +181,6 @@ impl SellerStatusResponse { .and_then(|link| link.href.strip_prefix('/')) .map(|link| format!("{}{}", paypal_base_url, link)) .ok_or(ApiErrorResponse::InternalServerError) - .into_report() .attach_printable("Merchant details not received in onboarding status") } } @@ -240,7 +239,6 @@ impl PartnerReferralResponse { .into_iter() .find(|hateoas_link| hateoas_link.rel == "action_url") .ok_or(ApiErrorResponse::InternalServerError) - .into_report() .attach_printable("Failed to get action_url from paypal response")? .href) } diff --git a/crates/router/src/types/api/fraud_check.rs b/crates/router/src/types/api/fraud_check.rs index e871cbc5d33..45c79930e80 100644 --- a/crates/router/src/types/api/fraud_check.rs +++ b/crates/router/src/types/api/fraud_check.rs @@ -2,7 +2,7 @@ use std::str::FromStr; use api_models::enums; use common_utils::errors::CustomResult; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use super::{BoxedConnector, ConnectorData, SessionConnectorData}; use crate::{ @@ -69,7 +69,6 @@ pub enum ConnectorCallType { impl FraudCheckConnectorData { pub fn get_connector_by_name(name: &str) -> CustomResult { let connector_name = enums::FrmConnectors::from_str(name) - .into_report() .change_context(errors::ApiErrorResponse::IncorrectConnectorNameGiven) .attach_printable_lazy(|| { format!("unable to parse connector: {:?}", name.to_string()) diff --git a/crates/router/src/types/api/payments.rs b/crates/router/src/types/api/payments.rs index d465300dd61..370e0ca3509 100644 --- a/crates/router/src/types/api/payments.rs +++ b/crates/router/src/types/api/payments.rs @@ -13,7 +13,7 @@ pub use api_models::payments::{ PgRedirectResponse, PhoneDetails, RedirectionResponse, SessionToken, TimeRange, UrlDetails, VerifyRequest, VerifyResponse, WalletData, }; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use crate::{ core::errors, @@ -99,7 +99,6 @@ impl PaymentIdTypeExt for PaymentIdType { | Self::PreprocessingId(_) => Err(errors::ValidationError::IncorrectValueProvided { field_name: "payment_id", }) - .into_report() .attach_printable("Expected payment intent ID but got connector transaction ID"), } } @@ -120,8 +119,8 @@ impl MandateValidationFieldsExt for MandateValidationFields { (Some(_), Some(_)) => Err(errors::ValidationError::InvalidValue { message: "Expected one out of recurring_details and mandate_data but got both" .to_string(), - }) - .into_report(), + } + .into()), (_, Some(_)) => Ok(Some(MandateTransactionType::RecurringMandateTransaction)), (Some(_), _) => Ok(Some(MandateTransactionType::NewMandateTransaction)), } diff --git a/crates/router/src/types/api/verify_connector.rs b/crates/router/src/types/api/verify_connector.rs index d05a2b8a8e2..85bb9bf72af 100644 --- a/crates/router/src/types/api/verify_connector.rs +++ b/crates/router/src/types/api/verify_connector.rs @@ -1,7 +1,7 @@ pub mod paypal; pub mod stripe; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use crate::{ consts, @@ -167,8 +167,8 @@ pub trait VerifyConnector { .change_context(errors::ApiErrorResponse::InternalServerError)?; Err(errors::ApiErrorResponse::InvalidRequestData { message: error.reason.unwrap_or(error.message), - }) - .into_report() + } + .into()) } async fn handle_access_token_error_response( @@ -183,7 +183,7 @@ pub trait VerifyConnector { .change_context(errors::ApiErrorResponse::InternalServerError)?; Err(errors::ApiErrorResponse::InvalidRequestData { message: error.reason.unwrap_or(error.message), - }) - .into_report() + } + .into()) } } diff --git a/crates/router/src/types/api/verify_connector/stripe.rs b/crates/router/src/types/api/verify_connector/stripe.rs index 3fc55291d9c..9dc7a2c244a 100644 --- a/crates/router/src/types/api/verify_connector/stripe.rs +++ b/crates/router/src/types/api/verify_connector/stripe.rs @@ -1,4 +1,4 @@ -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use router_env::env; use super::VerifyConnector; @@ -29,8 +29,8 @@ impl VerifyConnector for connector::Stripe { (env::Env::Production, "card_declined") => Ok(services::ApplicationResponse::StatusOk), _ => Err(errors::ApiErrorResponse::InvalidRequestData { message: error.reason.unwrap_or(error.message), - }) - .into_report(), + } + .into()), } } } diff --git a/crates/router/src/types/domain/address.rs b/crates/router/src/types/domain/address.rs index c657aaf97ea..458ccb8114d 100644 --- a/crates/router/src/types/domain/address.rs +++ b/crates/router/src/types/domain/address.rs @@ -79,7 +79,7 @@ impl behaviour::Conversion for Address { async { let inner_decrypt = |inner| types::decrypt(inner, key.peek()); let inner_decrypt_email = |inner| types::decrypt(inner, key.peek()); - Ok(Self { + Ok::>(Self { id: other.id, address_id: other.address_id, city: other.city, diff --git a/crates/router/src/types/domain/customer.rs b/crates/router/src/types/domain/customer.rs index d5f05944d6c..de95251d9d4 100644 --- a/crates/router/src/types/domain/customer.rs +++ b/crates/router/src/types/domain/customer.rs @@ -60,7 +60,7 @@ impl super::behaviour::Conversion for Customer { async { let inner_decrypt = |inner| types::decrypt(inner, key.peek()); let inner_decrypt_email = |inner| types::decrypt(inner, key.peek()); - Ok(Self { + Ok::>(Self { id: Some(item.id), customer_id: item.customer_id, merchant_id: item.merchant_id, diff --git a/crates/router/src/types/domain/event.rs b/crates/router/src/types/domain/event.rs index 1c39be5a3d2..5e198261169 100644 --- a/crates/router/src/types/domain/event.rs +++ b/crates/router/src/types/domain/event.rs @@ -85,7 +85,7 @@ impl super::behaviour::Conversion for Event { Self: Sized, { async { - Ok(Self { + Ok::>(Self { event_id: item.event_id, event_type: item.event_type, event_class: item.event_class, diff --git a/crates/router/src/types/domain/merchant_account.rs b/crates/router/src/types/domain/merchant_account.rs index 3832ffb3da7..99553e26157 100644 --- a/crates/router/src/types/domain/merchant_account.rs +++ b/crates/router/src/types/domain/merchant_account.rs @@ -195,7 +195,7 @@ impl super::behaviour::Conversion for MerchantAccount { Self: Sized, { async { - Ok(Self { + Ok::>(Self { id: Some(item.id), merchant_id: item.merchant_id, return_url: item.return_url, diff --git a/crates/router/src/types/domain/types.rs b/crates/router/src/types/domain/types.rs index d80b8d0cba6..0ef4e8579d3 100644 --- a/crates/router/src/types/domain/types.rs +++ b/crates/router/src/types/domain/types.rs @@ -5,7 +5,7 @@ use common_utils::{ ext_traits::AsyncExt, }; use diesel_models::encryption::Encryption; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use masking::{PeekInterface, Secret}; use router_env::{instrument, tracing}; @@ -58,7 +58,6 @@ impl< let data = crypt_algo.decode_message(key, encrypted.clone())?; let value: String = std::str::from_utf8(&data) - .into_report() .change_context(errors::CryptoError::DecodingFailed)? .to_string(); @@ -80,7 +79,6 @@ impl< crypt_algo: V, ) -> CustomResult { let data = serde_json::to_vec(&masked_data.peek()) - .into_report() .change_context(errors::CryptoError::DecodingFailed)?; let encrypted_data = crypt_algo.encode_message(key, &data)?; @@ -96,9 +94,8 @@ impl< let encrypted = encrypted_data.into_inner(); let data = crypt_algo.decode_message(key, encrypted.clone())?; - let value: serde_json::Value = serde_json::from_slice(&data) - .into_report() - .change_context(errors::CryptoError::DecodingFailed)?; + let value: serde_json::Value = + serde_json::from_slice(&data).change_context(errors::CryptoError::DecodingFailed)?; Ok(Self::new(value.into(), encrypted)) } diff --git a/crates/router/src/types/domain/user.rs b/crates/router/src/types/domain/user.rs index 176b5810158..4625a72f5dd 100644 --- a/crates/router/src/types/domain/user.rs +++ b/crates/router/src/types/domain/user.rs @@ -11,7 +11,7 @@ use diesel_models::{ user as storage_user, user_role::{UserRole, UserRoleNew}, }; -use error_stack::{IntoReport, ResultExt}; +use error_stack::{report, ResultExt}; use masking::{ExposeInterface, PeekInterface, Secret}; use once_cell::sync::Lazy; use router_env::env; @@ -319,8 +319,8 @@ impl NewUserMerchant { return Err(UserErrors::MerchantAccountCreationError(format!( "Merchant with {} already exists", self.get_merchant_id() - ))) - .into_report(); + )) + .into()); } Ok(()) } @@ -499,9 +499,9 @@ impl NewUser { Ok(user) => Ok(user.into()), Err(e) => { if e.current_context().is_db_unique_violation() { - return Err(e.change_context(UserErrors::UserExists)); + Err(e.change_context(UserErrors::UserExists)) } else { - return Err(e.change_context(UserErrors::InternalServerError)); + Err(e.change_context(UserErrors::InternalServerError)) } } } @@ -515,7 +515,7 @@ impl NewUser { .await .is_ok() { - return Err(UserErrors::UserExists).into_report(); + return Err(report!(UserErrors::UserExists)); } Ok(()) } diff --git a/crates/router/src/types/pm_auth.rs b/crates/router/src/types/pm_auth.rs index e2d08c6afea..555e8351ecf 100644 --- a/crates/router/src/types/pm_auth.rs +++ b/crates/router/src/types/pm_auth.rs @@ -1,6 +1,6 @@ use std::str::FromStr; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use pm_auth::{ connector::plaid, types::{ @@ -17,7 +17,6 @@ use crate::core::{ impl PaymentAuthConnectorDataExt for PaymentAuthConnectorData { fn get_connector_by_name(name: &str) -> errors::CustomResult { let connector_name = pm_auth_types::PaymentMethodAuthConnectors::from_str(name) - .into_report() .change_context(ApiErrorResponse::IncorrectConnectorNameGiven) .attach_printable_lazy(|| { format!("unable to parse connector: {:?}", name.to_string()) diff --git a/crates/router/src/types/storage/dispute.rs b/crates/router/src/types/storage/dispute.rs index 84a1f748bee..b76325acfc1 100644 --- a/crates/router/src/types/storage/dispute.rs +++ b/crates/router/src/types/storage/dispute.rs @@ -3,7 +3,7 @@ use common_utils::errors::CustomResult; use diesel::{associations::HasTable, ExpressionMethods, QueryDsl}; pub use diesel_models::dispute::{Dispute, DisputeNew, DisputeUpdate}; use diesel_models::{errors, query::generics::db_metrics, schema::dispute::dsl}; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use crate::{connection::PgPooledConn, logger}; @@ -69,7 +69,6 @@ impl DisputeDbExt for Dispute { db_metrics::DatabaseOperation::Filter, ) .await - .into_report() .change_context(errors::DatabaseError::NotFound) .attach_printable_lazy(|| "Error filtering records by predicate") } diff --git a/crates/router/src/types/storage/mandate.rs b/crates/router/src/types/storage/mandate.rs index 05a5733053f..648011ade31 100644 --- a/crates/router/src/types/storage/mandate.rs +++ b/crates/router/src/types/storage/mandate.rs @@ -5,7 +5,7 @@ pub use diesel_models::mandate::{ Mandate, MandateNew, MandateUpdate, MandateUpdateInternal, SingleUseMandate, }; use diesel_models::{errors, schema::mandate::dsl}; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use crate::{connection::PgPooledConn, logger}; @@ -63,7 +63,6 @@ impl MandateDbExt for Mandate { filter .get_results_async(conn) .await - .into_report() // The query built here returns an empty Vec when no records are found, and if any error does occur, // it would be an internal database error, due to which we are raising a DatabaseError::Unknown error .change_context(errors::DatabaseError::Others) diff --git a/crates/router/src/types/storage/payment_link.rs b/crates/router/src/types/storage/payment_link.rs index 4dd9e06b4b4..6b4869817cc 100644 --- a/crates/router/src/types/storage/payment_link.rs +++ b/crates/router/src/types/storage/payment_link.rs @@ -4,7 +4,7 @@ pub use diesel_models::{ payment_link::{PaymentLink, PaymentLinkNew}, schema::payment_link::dsl, }; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use crate::{ connection::PgPooledConn, @@ -57,7 +57,6 @@ impl PaymentLinkDbExt for PaymentLink { filter .get_results_async(conn) .await - .into_report() // The query built here returns an empty Vec when no records are found, and if any error does occur, // it would be an internal database error, due to which we are raising a DatabaseError::Unknown error .change_context(errors::DatabaseError::Others) diff --git a/crates/router/src/types/storage/refund.rs b/crates/router/src/types/storage/refund.rs index bb05233173c..76bdf8655f6 100644 --- a/crates/router/src/types/storage/refund.rs +++ b/crates/router/src/types/storage/refund.rs @@ -10,7 +10,7 @@ use diesel_models::{ query::generics::db_metrics, schema::refund::dsl, }; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use crate::{connection::PgPooledConn, logger}; @@ -123,7 +123,6 @@ impl RefundDbExt for Refund { db_metrics::DatabaseOperation::Filter, ) .await - .into_report() .change_context(errors::DatabaseError::NotFound) .attach_printable_lazy(|| "Error filtering records by predicate") } @@ -152,7 +151,6 @@ impl RefundDbExt for Refund { .order_by(dsl::connector.asc()) .get_results_async(conn) .await - .into_report() .change_context(errors::DatabaseError::Others) .attach_printable("Error filtering records by connector")?; @@ -163,7 +161,6 @@ impl RefundDbExt for Refund { .order_by(dsl::currency.asc()) .get_results_async(conn) .await - .into_report() .change_context(errors::DatabaseError::Others) .attach_printable("Error filtering records by currency")?; @@ -173,7 +170,6 @@ impl RefundDbExt for Refund { .order_by(dsl::refund_status.asc()) .get_results_async(conn) .await - .into_report() .change_context(errors::DatabaseError::Others) .attach_printable("Error filtering records by refund status")?; @@ -248,7 +244,6 @@ impl RefundDbExt for Refund { filter .get_result_async::(conn) .await - .into_report() .change_context(errors::DatabaseError::NotFound) .attach_printable_lazy(|| "Error filtering count of refunds") } diff --git a/crates/router/src/types/transformers.rs b/crates/router/src/types/transformers.rs index 2f0c9479914..8a53a58aabd 100644 --- a/crates/router/src/types/transformers.rs +++ b/crates/router/src/types/transformers.rs @@ -9,7 +9,7 @@ use common_utils::{ pii, }; use diesel_models::enums as storage_enums; -use error_stack::{report, IntoReport, ResultExt}; +use error_stack::{report, ResultExt}; use masking::{ExposeInterface, PeekInterface}; use super::domain; @@ -221,8 +221,7 @@ impl ForeignTryFrom for common_enums::RoutableConnectors { api_enums::Connector::Plaid => { Err(common_utils::errors::ValidationError::InvalidValue { message: "plaid is not a routable connector".to_string(), - }) - .into_report()? + })? } api_enums::Connector::Powertranz => Self::Powertranz, api_enums::Connector::Prophetpay => Self::Prophetpay, @@ -231,14 +230,12 @@ impl ForeignTryFrom for common_enums::RoutableConnectors { api_enums::Connector::Signifyd => { Err(common_utils::errors::ValidationError::InvalidValue { message: "signifyd is not a routable connector".to_string(), - }) - .into_report()? + })? } api_enums::Connector::Riskified => { Err(common_utils::errors::ValidationError::InvalidValue { message: "riskified is not a routable connector".to_string(), - }) - .into_report()? + })? } api_enums::Connector::Square => Self::Square, api_enums::Connector::Stax => Self::Stax, @@ -267,8 +264,7 @@ impl ForeignTryFrom for common_enums::RoutableConnectors { api_enums::Connector::Threedsecureio => { Err(common_utils::errors::ValidationError::InvalidValue { message: "threedsecureio is not a routable connector".to_string(), - }) - .into_report()? + })? } }) } diff --git a/crates/router/src/utils.rs b/crates/router/src/utils.rs index bfd3609d50f..56f68e33d3b 100644 --- a/crates/router/src/utils.rs +++ b/crates/router/src/utils.rs @@ -24,7 +24,7 @@ pub use common_utils::{ validation::validate_email, }; use data_models::payments::PaymentIntent; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use image::Luma; use masking::ExposeInterface; use nanoid::nanoid; @@ -127,32 +127,28 @@ impl ConnectorResponseExt for Result, error_stack::Report> { fn get_error_response(self) -> RouterResult { - self.change_context(errors::ApiErrorResponse::InternalServerError) + self.map_err(|error| error.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(errors::ApiErrorResponse::InternalServerError).attach_printable(format!( + "Expecting error response, received response: {res:?}" + )) } Err(err_res) => Ok(err_res), }) } fn get_response(self) -> RouterResult { - self.change_context(errors::ApiErrorResponse::InternalServerError) + self.map_err(|error| error.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:?}" - )) + Err(errors::ApiErrorResponse::InternalServerError).attach_printable(format!( + "Expecting response, received error response: {err_res:?}" + )) } Ok(res) => Ok(res), }) @@ -174,7 +170,6 @@ impl QrImage { data: String, ) -> Result> { let qr_code = qrcode::QrCode::new(data.as_bytes()) - .into_report() .change_context(common_utils::errors::QrCodeError::FailedToCreateQrCode)?; // Renders the QR code into an image. @@ -318,7 +313,6 @@ pub async fn find_payment_intent_from_mandate_id_type( &mandate .original_payment_id .ok_or(errors::ApiErrorResponse::InternalServerError) - .into_report() .attach_printable("original_payment_id not present in mandate record")?, &merchant_account.merchant_id, merchant_account.storage_scheme, @@ -434,7 +428,6 @@ pub fn handle_json_response_deserialization_failure( ); let response_data = String::from_utf8(res.response.to_vec()) - .into_report() .change_context(errors::ConnectorError::ResponseDeserializationFailed)?; // check for whether the response is in json format @@ -467,7 +460,6 @@ pub fn get_http_status_code_type( 400..=499 => "4xx", 500..=599 => "5xx", _ => Err(errors::ApiErrorResponse::InternalServerError) - .into_report() .attach_printable("Invalid http status code")?, }; Ok(status_code_type.to_string()) @@ -842,7 +834,6 @@ pub async fn flatten_join_error(handle: Handle) -> RouterResult { Ok(Ok(t)) => Ok(t), Ok(Err(err)) => Err(err), Err(err) => Err(err) - .into_report() .change_context(errors::ApiErrorResponse::InternalServerError) .attach_printable("Join Error"), } diff --git a/crates/router/src/utils/connector_onboarding/paypal.rs b/crates/router/src/utils/connector_onboarding/paypal.rs index ff9b5ab59e7..708763a4440 100644 --- a/crates/router/src/utils/connector_onboarding/paypal.rs +++ b/crates/router/src/utils/connector_onboarding/paypal.rs @@ -1,5 +1,5 @@ use common_utils::request::{Method, Request, RequestBuilder, RequestContent}; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use http::header; use crate::{ @@ -28,17 +28,16 @@ pub async fn generate_access_token(state: AppState) -> RouterResult for ExchangeRates { let mut conversion_usable: HashMap = HashMap::new(); for (curr, conversion) in value.conversion { let enum_curr = enums::Currency::from_str(curr.as_str()) - .into_report() .change_context(ForexCacheError::ConversionError)?; conversion_usable.insert(enum_curr, CurrencyFactors::from(conversion)); } let base_curr = enums::Currency::from_str(value.base_currency.as_str()) - .into_report() .change_context(ForexCacheError::ConversionError)?; Ok(Self { base_currency: base_curr, @@ -342,7 +340,6 @@ async fn fetch_forex_rates( let forex_response = response .json::() .await - .into_report() .change_context(ForexCacheError::ParsingError)?; logger::info!("{:?}", forex_response); @@ -399,7 +396,6 @@ pub async fn fallback_fetch_forex_rates( let fallback_forex_response = response .json::() .await - .into_report() .change_context(ForexCacheError::ParsingError)?; logger::info!("{:?}", fallback_forex_response); @@ -463,11 +459,11 @@ async fn acquire_redis_lock(app_state: &AppState) -> CustomResult UserResult { let now = common_utils::date_time::now(); let data_value = serde_json::to_value(metadata_value) - .into_report() .change_context(UserErrors::InternalServerError) .attach_printable("Error Converting Struct To Serde Value")?; state @@ -60,7 +59,6 @@ pub async fn insert_user_scoped_metadata_to_db( ) -> UserResult { let now = common_utils::date_time::now(); let data_value = serde_json::to_value(metadata_value) - .into_report() .change_context(UserErrors::InternalServerError) .attach_printable("Error Converting Struct To Serde Value")?; state @@ -131,7 +129,6 @@ pub async fn update_merchant_scoped_metadata( metadata_value: impl serde::Serialize, ) -> UserResult { let data_value = serde_json::to_value(metadata_value) - .into_report() .change_context(UserErrors::InternalServerError) .attach_printable("Error Converting Struct To Serde Value")?; @@ -160,7 +157,6 @@ pub async fn update_user_scoped_metadata( metadata_value: impl serde::Serialize, ) -> UserResult { let data_value = serde_json::to_value(metadata_value) - .into_report() .change_context(UserErrors::InternalServerError) .attach_printable("Error Converting Struct To Serde Value")?; @@ -187,7 +183,7 @@ where { data.map(|metadata| serde_json::from_value(metadata.data_value.clone())) .transpose() - .map_err(|_| UserErrors::InternalServerError.into()) + .change_context(UserErrors::InternalServerError) .attach_printable("Error Serializing Metadata from DB") } @@ -248,10 +244,10 @@ pub fn set_ip_address_if_required( if let SetMetaDataRequest::ProductionAgreement(req) = request { let ip_address_from_request: Secret = headers .get(headers::X_FORWARDED_FOR) - .ok_or(UserErrors::IpAddressParsingFailed.into()) + .ok_or(report!(UserErrors::IpAddressParsingFailed)) .attach_printable("X-Forwarded-For header not found")? .to_str() - .map_err(|_| UserErrors::IpAddressParsingFailed.into()) + .change_context(UserErrors::IpAddressParsingFailed) .attach_printable("Error converting Header Value to Str")? .split(',') .next() @@ -259,7 +255,7 @@ pub fn set_ip_address_if_required( let ip_addr: Result = ip.parse(); ip_addr.ok() }) - .ok_or(UserErrors::IpAddressParsingFailed.into()) + .ok_or(report!(UserErrors::IpAddressParsingFailed)) .attach_printable("Error Parsing header value to ip")? .to_string() .into(); @@ -274,7 +270,7 @@ pub fn parse_string_to_enums(query: String) -> UserResult, _>>() - .map_err(|_| UserErrors::InvalidMetadataRequest.into()) + .change_context(UserErrors::InvalidMetadataRequest) .attach_printable("Error Parsing to DashboardMetadata enums")?, }) } diff --git a/crates/router/src/utils/user/password.rs b/crates/router/src/utils/user/password.rs index cff17863c32..5ed8d83658d 100644 --- a/crates/router/src/utils/user/password.rs +++ b/crates/router/src/utils/user/password.rs @@ -6,7 +6,7 @@ use argon2::{ Argon2, }; use common_utils::errors::CustomResult; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use masking::{ExposeInterface, Secret}; use crate::core::errors::UserErrors; @@ -19,7 +19,6 @@ pub fn generate_password_hash( let argon2 = Argon2::default(); let password_hash = argon2 .hash_password(password.expose().as_bytes(), &salt) - .into_report() .change_context(UserErrors::InternalServerError)?; Ok(Secret::new(password_hash.to_string())) } @@ -29,15 +28,13 @@ pub fn is_correct_password( password: Secret, ) -> CustomResult { let password = password.expose(); - let parsed_hash = PasswordHash::new(&password) - .into_report() - .change_context(UserErrors::InternalServerError)?; + let parsed_hash = + PasswordHash::new(&password).change_context(UserErrors::InternalServerError)?; let result = Argon2::default().verify_password(candidate.expose().as_bytes(), &parsed_hash); match result { Ok(_) => Ok(true), Err(argon2Err::Password) => Ok(false), Err(e) => Err(e), } - .into_report() .change_context(UserErrors::InternalServerError) } diff --git a/crates/router/src/utils/user/sample_data.rs b/crates/router/src/utils/user/sample_data.rs index 8a09900c958..8469bf770d2 100644 --- a/crates/router/src/utils/user/sample_data.rs +++ b/crates/router/src/utils/user/sample_data.rs @@ -4,7 +4,7 @@ use api_models::{ }; use data_models::payments::payment_intent::PaymentIntentNew; use diesel_models::{user::sample_data::PaymentAttemptBatchNew, RefundNew}; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use rand::{prelude::SliceRandom, thread_rng, Rng}; use time::OffsetDateTime; @@ -44,7 +44,6 @@ pub async fn generate_sample_data( let merchant_parsed_details: Vec = serde_json::from_value(merchant_from_db.primary_business_details.clone()) - .into_report() .change_context(SampleDataError::InternalServerError) .attach_printable("Error while parsing primary business details")?; @@ -84,7 +83,6 @@ pub async fn generate_sample_data( // 10 percent payments should be failed #[allow(clippy::as_conversions)] let failure_attempts = usize::try_from((sample_data_size as f32 / 10.0).round() as i64) - .into_report() .change_context(SampleDataError::InvalidParameters)?; let failure_after_attempts = sample_data_size / failure_attempts; @@ -92,7 +90,6 @@ pub async fn generate_sample_data( // 20 percent refunds for payments #[allow(clippy::as_conversions)] let number_of_refunds = usize::try_from((sample_data_size as f32 / 5.0).round() as i64) - .into_report() .change_context(SampleDataError::InvalidParameters)?; let mut refunds_count = 0; diff --git a/crates/router/src/utils/user_role.rs b/crates/router/src/utils/user_role.rs index 23b5bcf0f38..1fb58f983af 100644 --- a/crates/router/src/utils/user_role.rs +++ b/crates/router/src/utils/user_role.rs @@ -3,7 +3,7 @@ use std::collections::HashSet; use api_models::user_role as user_role_api; use common_enums::PermissionGroup; use diesel_models::user_role::UserRole; -use error_stack::{IntoReport, ResultExt}; +use error_stack::{report, ResultExt}; use router_env::logger; use crate::{ @@ -52,19 +52,19 @@ impl From for user_role_api::Permission { pub fn validate_role_groups(groups: &[PermissionGroup]) -> UserResult<()> { if groups.is_empty() { - return Err(UserErrors::InvalidRoleOperation.into()) + return Err(report!(UserErrors::InvalidRoleOperation)) .attach_printable("Role groups cannot be empty"); } let unique_groups: HashSet<_> = groups.iter().cloned().collect(); if unique_groups.contains(&PermissionGroup::OrganizationManage) { - return Err(UserErrors::InvalidRoleOperation.into()) + return Err(report!(UserErrors::InvalidRoleOperation)) .attach_printable("Organization manage group cannot be added to role"); } if unique_groups.len() != groups.len() { - return Err(UserErrors::InvalidRoleOperation.into()) + return Err(report!(UserErrors::InvalidRoleOperation)) .attach_printable("Duplicate permission group found"); } @@ -133,9 +133,7 @@ pub async fn set_role_permissions_in_cache_if_required( state, role_id, &role_info.get_permissions_set().into_iter().collect(), - consts::JWT_TOKEN_TIME_IN_SECS - .try_into() - .into_report() + i64::try_from(consts::JWT_TOKEN_TIME_IN_SECS) .change_context(UserErrors::InternalServerError)?, ) .await diff --git a/crates/router/src/utils/verify_connector.rs b/crates/router/src/utils/verify_connector.rs index 060f92d0e5a..acb2f609631 100644 --- a/crates/router/src/utils/verify_connector.rs +++ b/crates/router/src/utils/verify_connector.rs @@ -1,5 +1,5 @@ use api_models::enums::Connector; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use crate::{core::errors, types::api}; @@ -11,8 +11,7 @@ pub fn generate_card_from_details( ) -> errors::RouterResult { Ok(api::Card { card_number: card_number - .parse() - .into_report() + .parse::() .change_context(errors::ApiErrorResponse::InternalServerError) .attach_printable("Error while parsing card number")?, card_issuer: None, diff --git a/crates/router_env/Cargo.toml b/crates/router_env/Cargo.toml index a028dfb8e56..c161d02b8d2 100644 --- a/crates/router_env/Cargo.toml +++ b/crates/router_env/Cargo.toml @@ -10,7 +10,7 @@ license.workspace = true [dependencies] cargo_metadata = "0.18.1" config = { version = "0.13.3", features = ["toml"] } -error-stack = "0.3.1" +error-stack = "0.4.1" gethostname = "0.4.3" once_cell = "1.18.0" opentelemetry = { version = "0.19.0", features = ["rt-tokio-current-thread", "metrics"] } diff --git a/crates/scheduler/Cargo.toml b/crates/scheduler/Cargo.toml index cad5dec6283..4f2a423709f 100644 --- a/crates/scheduler/Cargo.toml +++ b/crates/scheduler/Cargo.toml @@ -12,7 +12,7 @@ email = ["external_services/email"] [dependencies] # Third party crates async-trait = "0.1.68" -error-stack = "0.3.1" +error-stack = "0.4.1" futures = "0.3.28" num_cpus = "1.15.0" once_cell = "1.18.0" diff --git a/crates/scheduler/src/consumer.rs b/crates/scheduler/src/consumer.rs index 471f689ffc8..a95ac493247 100644 --- a/crates/scheduler/src/consumer.rs +++ b/crates/scheduler/src/consumer.rs @@ -7,7 +7,7 @@ pub mod workflows; use common_utils::{errors::CustomResult, signals::get_allowed_signals}; use diesel_models::enums; pub use diesel_models::{self, process_tracker as storage}; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use futures::future; use redis_interface::{RedisConnectionPool, RedisEntryId}; use router_env::{ @@ -48,7 +48,6 @@ pub async fn start_consumer( #[allow(unknown_lints)] #[allow(clippy::unnecessary_fallible_conversions)] let timeout = Uniform::try_from(0..=settings.loop_interval) - .into_report() .change_context(errors::ProcessTrackerError::ConfigurationError)?; tokio::time::sleep(Duration::from_millis(timeout.sample(&mut rng))).await; @@ -64,7 +63,6 @@ pub async fn start_consumer( logger::error!(?error, "Signal Handler Error"); errors::ProcessTrackerError::ConfigurationError }) - .into_report() .attach_printable("Failed while creating a signals handler")?; let handle = signal.handle(); let task_handle = @@ -112,7 +110,6 @@ pub async fn start_consumer( handle.close(); task_handle .await - .into_report() .change_context(errors::ProcessTrackerError::UnexpectedFlow)?; Ok(()) diff --git a/crates/scheduler/src/consumer/types/batch.rs b/crates/scheduler/src/consumer/types/batch.rs index b9748e1ecac..50c6f39465f 100644 --- a/crates/scheduler/src/consumer/types/batch.rs +++ b/crates/scheduler/src/consumer/types/batch.rs @@ -2,7 +2,7 @@ use std::collections::HashMap; use common_utils::{errors::CustomResult, ext_traits::OptionExt}; use diesel_models::process_tracker::ProcessTracker; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use time::PrimitiveDateTime; use crate::errors; @@ -35,7 +35,6 @@ impl ProcessTrackerBatch { ( "trackers", serde_json::to_string(&self.trackers) - .into_report() .change_context(errors::ProcessTrackerError::SerializationFailed) .attach_printable_lazy(|| { format!("Unable to stringify trackers: {:?}", self.trackers) @@ -79,12 +78,10 @@ impl ProcessTrackerBatch { let offset_date_time = time::OffsetDateTime::from_unix_timestamp( created_time .as_str() - .parse() - .into_report() + .parse::() .change_context(errors::ParsingError::UnknownError) .change_context(errors::ProcessTrackerError::DeserializationFailed)?, ) - .into_report() .attach_printable_lazy(|| format!("Unable to parse time {}", &created_time)) .change_context(errors::ProcessTrackerError::MissingRequiredField)?; PrimitiveDateTime::new(offset_date_time.date(), offset_date_time.time()) @@ -102,12 +99,12 @@ impl ProcessTrackerBatch { .change_context(errors::ProcessTrackerError::MissingRequiredField)?; let trackers = serde_json::from_str::>(trackers.as_str()) - .into_report() .change_context(errors::ParsingError::UnknownError) .attach_printable_lazy(|| { format!("Unable to parse trackers from JSON string: {trackers:?}") }) - .change_context(errors::ProcessTrackerError::DeserializationFailed)?; + .change_context(errors::ProcessTrackerError::DeserializationFailed) + .attach_printable("Error parsing ProcessTracker from redis stream entry")?; Ok(Self { id, @@ -118,6 +115,5 @@ impl ProcessTrackerBatch { rule, trackers, }) - .attach_printable("Error parsing ProcessTracker from redis stream entry") } } diff --git a/crates/scheduler/src/db/process_tracker.rs b/crates/scheduler/src/db/process_tracker.rs index ac20d4b293f..feb201f8b75 100644 --- a/crates/scheduler/src/db/process_tracker.rs +++ b/crates/scheduler/src/db/process_tracker.rs @@ -1,7 +1,7 @@ use common_utils::errors::CustomResult; pub use diesel_models as storage; use diesel_models::enums as storage_enums; -use error_stack::{IntoReport, ResultExt}; +use error_stack::{report, ResultExt}; use storage_impl::{connection, errors, mock_db::MockDb}; use time::PrimitiveDateTime; @@ -73,8 +73,7 @@ impl ProcessTrackerInterface for Store { let conn = connection::pg_connection_read(self).await?; storage::ProcessTracker::find_process_by_id(&conn, id) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } async fn reinitialize_limbo_processes( @@ -85,8 +84,7 @@ impl ProcessTrackerInterface for Store { let conn = connection::pg_connection_write(self).await?; storage::ProcessTracker::reinitialize_limbo_processes(&conn, ids, schedule_time) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } async fn find_processes_by_time_status( @@ -105,8 +103,7 @@ impl ProcessTrackerInterface for Store { limit, ) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } async fn insert_process( @@ -116,8 +113,7 @@ impl ProcessTrackerInterface for Store { let conn = connection::pg_connection_write(self).await?; new.insert_process(&conn) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } async fn update_process( @@ -128,8 +124,7 @@ impl ProcessTrackerInterface for Store { let conn = connection::pg_connection_write(self).await?; this.update(&conn, process) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } async fn reset_process( @@ -194,8 +189,7 @@ impl ProcessTrackerInterface for Store { let conn = connection::pg_connection_write(self).await?; storage::ProcessTracker::update_process_status_by_ids(&conn, task_ids, task_update) .await - .map_err(Into::into) - .into_report() + .map_err(|error| report!(errors::StorageError::from(error))) } } diff --git a/crates/scheduler/src/producer.rs b/crates/scheduler/src/producer.rs index b8081c2b9ae..fd2b9b654a4 100644 --- a/crates/scheduler/src/producer.rs +++ b/crates/scheduler/src/producer.rs @@ -2,7 +2,7 @@ use std::sync::Arc; use common_utils::errors::CustomResult; use diesel_models::enums::ProcessTrackerStatus; -use error_stack::{report, IntoReport, ResultExt}; +use error_stack::{report, ResultExt}; use router_env::{ instrument, tracing::{self, Instrument}, @@ -39,7 +39,6 @@ where #[allow(unknown_lints)] #[allow(clippy::unnecessary_fallible_conversions)] let timeout = Uniform::try_from(0..=scheduler_settings.loop_interval) - .into_report() .change_context(errors::ProcessTrackerError::ConfigurationError)?; tokio::time::sleep(Duration::from_millis(timeout.sample(&mut rng))).await; @@ -57,7 +56,6 @@ where logger::error!("Signal Handler Error: {:?}", error); errors::ProcessTrackerError::ConfigurationError }) - .into_report() .attach_printable("Failed while creating a signals handler")?; let handle = signal.handle(); let task_handle = @@ -89,7 +87,6 @@ where handle.close(); task_handle .await - .into_report() .change_context(errors::ProcessTrackerError::UnexpectedFlow)?; Ok(()) diff --git a/crates/storage_impl/Cargo.toml b/crates/storage_impl/Cargo.toml index 0bffd846506..d7107cdccfa 100644 --- a/crates/storage_impl/Cargo.toml +++ b/crates/storage_impl/Cargo.toml @@ -35,7 +35,7 @@ config = { version = "0.13.3", features = ["toml"] } crc32fast = "1.3.2" diesel = { version = "2.1.0", default-features = false, features = ["postgres"] } dyn-clone = "1.0.12" -error-stack = "0.3.1" +error-stack = "0.4.1" futures = "0.3.28" http = "0.2.9" mime = "0.3.17" diff --git a/crates/storage_impl/src/connection.rs b/crates/storage_impl/src/connection.rs index 2ac90521ba4..4d19f3820e9 100644 --- a/crates/storage_impl/src/connection.rs +++ b/crates/storage_impl/src/connection.rs @@ -1,7 +1,7 @@ use bb8::PooledConnection; use common_utils::errors; use diesel::PgConnection; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; pub type PgPool = bb8::Pool>; @@ -43,7 +43,6 @@ pub async fn pg_connection_read( pool.get() .await - .into_report() .change_context(crate::errors::StorageError::DatabaseConnectionError) } @@ -58,6 +57,5 @@ pub async fn pg_connection_write( pool.get() .await - .into_report() .change_context(crate::errors::StorageError::DatabaseConnectionError) } diff --git a/crates/storage_impl/src/database/store.rs b/crates/storage_impl/src/database/store.rs index 75c34af14ac..92ba8910bfb 100644 --- a/crates/storage_impl/src/database/store.rs +++ b/crates/storage_impl/src/database/store.rs @@ -2,7 +2,7 @@ use async_bb8_diesel::{AsyncConnection, ConnectionError}; use bb8::CustomizeConnection; use data_models::errors::{StorageError, StorageResult}; use diesel::PgConnection; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use masking::PeekInterface; use crate::config::Database; @@ -99,7 +99,6 @@ pub async fn diesel_make_pg_pool( pool.build(manager) .await - .into_report() .change_context(StorageError::InitializationError) .attach_printable("Failed to create PostgreSQL connection pool") } diff --git a/crates/storage_impl/src/lookup.rs b/crates/storage_impl/src/lookup.rs index c96e2451577..12d91ba5e95 100644 --- a/crates/storage_impl/src/lookup.rs +++ b/crates/storage_impl/src/lookup.rs @@ -6,7 +6,7 @@ use diesel_models::{ ReverseLookup as DieselReverseLookup, ReverseLookupNew as DieselReverseLookupNew, }, }; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use redis_interface::SetnxReply; use crate::{ @@ -42,7 +42,6 @@ impl ReverseLookupInterface for RouterStore { .get_master_pool() .get() .await - .into_report() .change_context(errors::StorageError::DatabaseConnectionError)?; new.insert(&conn).await.map_err(|er| { let new_err = diesel_error_to_data_error(er.current_context()); @@ -105,8 +104,8 @@ impl ReverseLookupInterface for KVRouterStore { Ok(SetnxReply::KeyNotSet) => Err(errors::StorageError::DuplicateValue { entity: "reverse_lookup", key: Some(created_rev_lookup.lookup_id.clone()), - }) - .into_report(), + } + .into()), Err(er) => Err(er).change_context(errors::StorageError::KVError), } } diff --git a/crates/storage_impl/src/mock_db/payment_intent.rs b/crates/storage_impl/src/mock_db/payment_intent.rs index 03e6539f162..a693eb5e261 100644 --- a/crates/storage_impl/src/mock_db/payment_intent.rs +++ b/crates/storage_impl/src/mock_db/payment_intent.rs @@ -8,7 +8,7 @@ use data_models::{ }, }; use diesel_models::enums as storage_enums; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use super::MockDb; use crate::DataModelExt; @@ -66,11 +66,7 @@ impl PaymentIntentInterface for MockDb { let time = common_utils::date_time::now(); let payment_intent = PaymentIntent { #[allow(clippy::as_conversions)] - id: payment_intents - .len() - .try_into() - .into_report() - .change_context(StorageError::MockDbError)?, + id: i32::try_from(payment_intents.len()).change_context(StorageError::MockDbError)?, payment_id: new.payment_id, merchant_id: new.merchant_id, status: new.status, diff --git a/crates/storage_impl/src/payments/payment_attempt.rs b/crates/storage_impl/src/payments/payment_attempt.rs index 04e755fa430..b8b97628db7 100644 --- a/crates/storage_impl/src/payments/payment_attempt.rs +++ b/crates/storage_impl/src/payments/payment_attempt.rs @@ -23,7 +23,7 @@ use diesel_models::{ }, reverse_lookup::{ReverseLookup, ReverseLookupNew}, }; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use redis_interface::HsetnxReply; use router_env::{instrument, tracing}; @@ -299,7 +299,6 @@ impl PaymentAttemptInterface for RouterStore { .get_replica_pool() .get() .await - .into_report() .change_context(errors::StorageError::DatabaseConnectionError)?; let connector_strings = connector.as_ref().map(|connector| { connector @@ -449,8 +448,8 @@ impl PaymentAttemptInterface for KVRouterStore { Ok(HsetnxReply::KeyNotSet) => Err(errors::StorageError::DuplicateValue { entity: "payment attempt", key: Some(key), - }) - .into_report(), + } + .into()), Ok(HsetnxReply::KeySet) => Ok(created_attempt), Err(error) => Err(error.change_context(errors::StorageError::KVError)), } @@ -483,7 +482,6 @@ impl PaymentAttemptInterface for KVRouterStore { ); // Check for database presence as well Maybe use a read replica here ? let redis_value = serde_json::to_string(&updated_attempt) - .into_report() .change_context(errors::StorageError::KVError)?; let field = format!("pa_{}", updated_attempt.attempt_id); diff --git a/crates/storage_impl/src/payments/payment_intent.rs b/crates/storage_impl/src/payments/payment_intent.rs index 40627d1eeba..6323c9a9850 100644 --- a/crates/storage_impl/src/payments/payment_intent.rs +++ b/crates/storage_impl/src/payments/payment_intent.rs @@ -28,7 +28,7 @@ use diesel_models::{ query::generics::db_metrics, schema::{payment_attempt::dsl as pa_dsl, payment_intent::dsl as pi_dsl}, }; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use redis_interface::HsetnxReply; #[cfg(feature = "olap")] use router_env::logger; @@ -128,8 +128,8 @@ impl PaymentIntentInterface for KVRouterStore { Ok(HsetnxReply::KeyNotSet) => Err(StorageError::DuplicateValue { entity: "payment_intent", key: Some(key), - }) - .into_report(), + } + .into()), Ok(HsetnxReply::KeySet) => Ok(created_intent), Err(error) => Err(error.change_context(StorageError::KVError)), } @@ -508,8 +508,8 @@ impl PaymentIntentInterface for crate::RouterStore { error_stack::report!(diesel_models::errors::DatabaseError::from(er)) .attach_printable("Error filtering payment records"), ) + .into() }) - .into_report() } #[cfg(feature = "olap")] @@ -663,8 +663,8 @@ impl PaymentIntentInterface for crate::RouterStore { error_stack::report!(diesel_models::errors::DatabaseError::from(er)) .attach_printable("Error filtering payment records"), ) + .into() }) - .into_report() } #[cfg(feature = "olap")] @@ -731,8 +731,8 @@ impl PaymentIntentInterface for crate::RouterStore { error_stack::report!(diesel_models::errors::DatabaseError::from(er)) .attach_printable("Error filtering payment records"), ) + .into() }) - .into_report() } } diff --git a/crates/storage_impl/src/payouts/payout_attempt.rs b/crates/storage_impl/src/payouts/payout_attempt.rs index c52291253ef..1f6c02c1fba 100644 --- a/crates/storage_impl/src/payouts/payout_attempt.rs +++ b/crates/storage_impl/src/payouts/payout_attempt.rs @@ -21,7 +21,7 @@ use diesel_models::{ }, ReverseLookupNew, }; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use redis_interface::HsetnxReply; use router_env::{instrument, logger, tracing}; @@ -115,8 +115,8 @@ impl PayoutAttemptInterface for KVRouterStore { Ok(HsetnxReply::KeyNotSet) => Err(errors::StorageError::DuplicateValue { entity: "payout attempt", key: Some(key), - }) - .into_report(), + } + .into()), Ok(HsetnxReply::KeySet) => Ok(created_attempt), Err(error) => Err(error.change_context(errors::StorageError::KVError)), } diff --git a/crates/storage_impl/src/payouts/payouts.rs b/crates/storage_impl/src/payouts/payouts.rs index c42ed120178..c6ff6250d48 100644 --- a/crates/storage_impl/src/payouts/payouts.rs +++ b/crates/storage_impl/src/payouts/payouts.rs @@ -23,7 +23,7 @@ use diesel_models::{ query::generics::db_metrics, schema::{payout_attempt::dsl as poa_dsl, payouts::dsl as po_dsl}, }; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use redis_interface::HsetnxReply; #[cfg(feature = "olap")] use router_env::logger; @@ -100,8 +100,8 @@ impl PayoutsInterface for KVRouterStore { Ok(HsetnxReply::KeyNotSet) => Err(StorageError::DuplicateValue { entity: "payouts", key: Some(key), - }) - .into_report(), + } + .into()), Ok(HsetnxReply::KeySet) => Ok(created_payout), Err(error) => Err(error.change_context(StorageError::KVError)), } @@ -474,8 +474,8 @@ impl PayoutsInterface for crate::RouterStore { error_stack::report!(diesel_models::errors::DatabaseError::from(er)) .attach_printable("Error filtering payout records"), ) + .into() }) - .into_report() } #[cfg(feature = "olap")] @@ -603,8 +603,8 @@ impl PayoutsInterface for crate::RouterStore { error_stack::report!(diesel_models::errors::DatabaseError::from(er)) .attach_printable("Error filtering payout records"), ) + .into() }) - .into_report() } #[cfg(feature = "olap")] diff --git a/crates/storage_impl/src/redis.rs b/crates/storage_impl/src/redis.rs index be82d4cc293..d431b458291 100644 --- a/crates/storage_impl/src/redis.rs +++ b/crates/storage_impl/src/redis.rs @@ -4,7 +4,7 @@ pub mod pub_sub; use std::sync::{atomic, Arc}; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use redis_interface::PubsubInterface; use router_env::{logger, tracing::Instrument}; @@ -53,7 +53,6 @@ impl RedisStore { .subscriber .subscribe::<(), _>(channel) .await - .into_report() .change_context(redis_interface::errors::RedisError::SubscribeError)?; let redis_clone = self.redis_conn.clone(); diff --git a/crates/storage_impl/src/redis/kv_store.rs b/crates/storage_impl/src/redis/kv_store.rs index 310e6e2dc5c..c7e6efc0b3b 100644 --- a/crates/storage_impl/src/redis/kv_store.rs +++ b/crates/storage_impl/src/redis/kv_store.rs @@ -1,7 +1,7 @@ use std::{fmt::Debug, sync::Arc}; use common_utils::errors::CustomResult; -use error_stack::IntoReport; +use error_stack::report; use redis_interface::errors::RedisError; use router_derive::TryGetEnumVariant; use router_env::logger; @@ -136,7 +136,7 @@ where .await .and_then(|result| { if result.is_empty() { - Err(RedisError::NotFound).into_report() + Err(report!(RedisError::NotFound)) } else { Ok(result) } @@ -159,7 +159,7 @@ where .await?; Ok(KvResult::HSetNx(result)) } else { - Err(RedisError::SetNxFailed).into_report() + Err(report!(RedisError::SetNxFailed)) } } @@ -178,7 +178,7 @@ where .await?; Ok(KvResult::SetNx(result)) } else { - Err(RedisError::SetNxFailed).into_report() + Err(report!(RedisError::SetNxFailed)) } } diff --git a/crates/storage_impl/src/redis/pub_sub.rs b/crates/storage_impl/src/redis/pub_sub.rs index c00ed13facf..349d1872d2a 100644 --- a/crates/storage_impl/src/redis/pub_sub.rs +++ b/crates/storage_impl/src/redis/pub_sub.rs @@ -1,4 +1,4 @@ -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use redis_interface::{errors as redis_errors, PubsubInterface, RedisValue}; use router_env::logger; @@ -27,7 +27,6 @@ impl PubSubInterface for redis_interface::RedisConnectionPool { self.subscriber .subscribe(channel) .await - .into_report() .change_context(redis_errors::RedisError::SubscribeError) } @@ -40,7 +39,6 @@ impl PubSubInterface for redis_interface::RedisConnectionPool { self.publisher .publish(channel, RedisValue::from(key).into_inner()) .await - .into_report() .change_context(redis_errors::RedisError::SubscribeError) } @@ -50,8 +48,7 @@ impl PubSubInterface for redis_interface::RedisConnectionPool { let mut rx = self.subscriber.on_message(); while let Ok(message) = rx.recv().await { logger::debug!("Invalidating {message:?}"); - let key: CacheKind<'_> = match RedisValue::new(message.value) - .try_into() + let key = match CacheKind::try_from(RedisValue::new(message.value)) .change_context(redis_errors::RedisError::OnMessageError) { Ok(value) => value, diff --git a/crates/storage_impl/src/utils.rs b/crates/storage_impl/src/utils.rs index 6d69f02593f..78198e92753 100644 --- a/crates/storage_impl/src/utils.rs +++ b/crates/storage_impl/src/utils.rs @@ -1,7 +1,7 @@ use bb8::PooledConnection; use data_models::errors::StorageError; use diesel::PgConnection; -use error_stack::{IntoReport, ResultExt}; +use error_stack::ResultExt; use crate::{errors::RedisErrorExt, metrics, DatabaseStore}; @@ -28,7 +28,6 @@ pub async fn pg_connection_read( pool.get() .await - .into_report() .change_context(StorageError::DatabaseConnectionError) } @@ -43,7 +42,6 @@ pub async fn pg_connection_write( pool.get() .await - .into_report() .change_context(StorageError::DatabaseConnectionError) } From 78befb42a35b1f98b1bd47b253d3c06e50bb2ee4 Mon Sep 17 00:00:00 2001 From: Bernard Eugine <114725419+bernard-eugine@users.noreply.github.com> Date: Mon, 1 Apr 2024 12:59:54 +0530 Subject: [PATCH 19/20] docs(README): remove link to outdated early access form --- README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.md b/README.md index 90398bf6d15..2be649b1db6 100644 --- a/README.md +++ b/README.md @@ -70,8 +70,6 @@ The fastest and easiest way to try Hyperswitch is via our CDK scripts 3. Follow the instructions provided on the console to successfully deploy Hyperswitch -For an early access to the production-ready setup fill this Early Access Form - ### Run it on your system You can run Hyperswitch on your system using Docker Compose after cloning this repository: From a843713126cea102064b342b6fc82429d89d758a Mon Sep 17 00:00:00 2001 From: Prajjwal Kumar Date: Mon, 1 Apr 2024 12:44:39 +0530 Subject: [PATCH 20/20] refactor(core): removed the processing status for payment_method_status (#4213) --- crates/common_enums/src/enums.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/crates/common_enums/src/enums.rs b/crates/common_enums/src/enums.rs index bbabab3a4e7..548e721f0d3 100644 --- a/crates/common_enums/src/enums.rs +++ b/crates/common_enums/src/enums.rs @@ -1253,7 +1253,6 @@ pub enum PaymentMethodStatus { impl From for PaymentMethodStatus { fn from(attempt_status: AttemptStatus) -> Self { match attempt_status { - AttemptStatus::Charged | AttemptStatus::Authorized => Self::Active, AttemptStatus::Failure => Self::Inactive, AttemptStatus::Voided | AttemptStatus::Started @@ -1275,7 +1274,9 @@ impl From for PaymentMethodStatus { | AttemptStatus::PartialCharged | AttemptStatus::PartialChargedAndChargeable | AttemptStatus::ConfirmationAwaited - | AttemptStatus::DeviceDataCollectionPending => Self::Processing, + | AttemptStatus::DeviceDataCollectionPending + | AttemptStatus::Charged + | AttemptStatus::Authorized => Self::Active, } } }