Bug: [enhancement]:Add scoped error enum for customer error



tracked in #1579 

We wanna use scoped errors + Errorswitch for customer API's

Currently customer API's returns the common errors enum...
It uses 
```
CustomerRedacted
CustomerNotFound
MandateNotFound
& a lot of InternalServerError's
```

instead we need to figure the errors raised here & add the corresponding variants...

diff --git a/crates/router/src/compatibility/stripe/customers.rs b/crates/router/src/compatibility/stripe/customers.rs
index 0a2cc27f376..f3f55418d3b 100644
--- a/crates/router/src/compatibility/stripe/customers.rs
+++ b/crates/router/src/compatibility/stripe/customers.rs
@@ -39,6 +39,7 @@ pub async fn customer_create(
         _,
         types::CreateCustomerResponse,
         errors::StripeErrorCode,
+        _,
     >(
         flow,
         state.get_ref(),
@@ -73,6 +74,7 @@ pub async fn customer_retrieve(
         _,
         types::CustomerRetrieveResponse,
         errors::StripeErrorCode,
+        _,
     >(
         flow,
         state.get_ref(),
@@ -116,6 +118,7 @@ pub async fn customer_update(
         _,
         types::CustomerUpdateResponse,
         errors::StripeErrorCode,
+        _,
     >(
         flow,
         state.get_ref(),
@@ -150,6 +153,7 @@ pub async fn customer_delete(
         _,
         types::CustomerDeleteResponse,
         errors::StripeErrorCode,
+        _,
     >(
         flow,
         state.get_ref(),
@@ -183,6 +187,7 @@ pub async fn list_customer_payment_method_api(
         _,
         types::CustomerPaymentMethodListResponse,
         errors::StripeErrorCode,
+        _,
     >(
         flow,
         state.get_ref(),
diff --git a/crates/router/src/compatibility/stripe/errors.rs b/crates/router/src/compatibility/stripe/errors.rs
index 8c3c62b01fa..769f6d1943e 100644
--- a/crates/router/src/compatibility/stripe/errors.rs
+++ b/crates/router/src/compatibility/stripe/errors.rs
@@ -1,5 +1,7 @@
 #![allow(unused_variables)]
-use crate::core::errors;
+use common_utils::errors::ErrorSwitch;
+
+use crate::core::errors::{self, CustomersErrorResponse};
 
 #[derive(Debug, router_derive::ApiError, Clone)]
 #[error(error_type_enum = StripeErrorType)]
@@ -694,10 +696,22 @@ impl From<serde_qs::Error> for StripeErrorCode {
     }
 }
 
-impl common_utils::errors::ErrorSwitch<StripeErrorCode> for errors::ApiErrorResponse {
+impl ErrorSwitch<StripeErrorCode> for errors::ApiErrorResponse {
     fn switch(&self) -> StripeErrorCode {
         self.clone().into()
     }
 }
 
 impl crate::services::EmbedError for error_stack::Report<StripeErrorCode> {}
+
+impl ErrorSwitch<StripeErrorCode> for CustomersErrorResponse {
+    fn switch(&self) -> StripeErrorCode {
+        use StripeErrorCode as SC;
+        match self {
+            Self::CustomerRedacted => SC::CustomerRedacted,
+            Self::InternalServerError => SC::InternalServerError,
+            Self::MandateActive => SC::MandateActive,
+            Self::CustomerNotFound => SC::CustomerNotFound,
+        }
+    }
+}
diff --git a/crates/router/src/compatibility/stripe/payment_intents.rs b/crates/router/src/compatibility/stripe/payment_intents.rs
index 0efb44d9d71..0f31f69934c 100644
--- a/crates/router/src/compatibility/stripe/payment_intents.rs
+++ b/crates/router/src/compatibility/stripe/payment_intents.rs
@@ -44,6 +44,7 @@ pub async fn payment_intents_create(
         _,
         types::StripePaymentIntentResponse,
         errors::StripeErrorCode,
+        _,
     >(
         flow,
         state.get_ref(),
@@ -101,6 +102,7 @@ pub async fn payment_intents_retrieve(
         _,
         types::StripePaymentIntentResponse,
         errors::StripeErrorCode,
+        _,
     >(
         flow,
         state.get_ref(),
@@ -162,6 +164,7 @@ pub async fn payment_intents_retrieve_with_gateway_creds(
         _,
         types::StripePaymentIntentResponse,
         errors::StripeErrorCode,
+        _,
     >(
         flow,
         state.get_ref(),
@@ -224,6 +227,7 @@ pub async fn payment_intents_update(
         _,
         types::StripePaymentIntentResponse,
         errors::StripeErrorCode,
+        _,
     >(
         flow,
         state.get_ref(),
@@ -288,6 +292,7 @@ pub async fn payment_intents_confirm(
         _,
         types::StripePaymentIntentResponse,
         errors::StripeErrorCode,
+        _,
     >(
         flow,
         state.get_ref(),
@@ -342,6 +347,7 @@ pub async fn payment_intents_capture(
         _,
         types::StripePaymentIntentResponse,
         errors::StripeErrorCode,
+        _,
     >(
         flow,
         state.get_ref(),
@@ -400,6 +406,7 @@ pub async fn payment_intents_cancel(
         _,
         types::StripePaymentIntentResponse,
         errors::StripeErrorCode,
+        _,
     >(
         flow,
         state.get_ref(),
@@ -444,6 +451,7 @@ pub async fn payment_intent_list(
         _,
         types::StripePaymentIntentListResponse,
         errors::StripeErrorCode,
+        _,
     >(
         flow,
         state.get_ref(),
diff --git a/crates/router/src/compatibility/stripe/refunds.rs b/crates/router/src/compatibility/stripe/refunds.rs
index 55de7b6bb59..62d79c32ad1 100644
--- a/crates/router/src/compatibility/stripe/refunds.rs
+++ b/crates/router/src/compatibility/stripe/refunds.rs
@@ -40,6 +40,7 @@ pub async fn refund_create(
         _,
         types::StripeRefundResponse,
         errors::StripeErrorCode,
+        _,
     >(
         flow,
         state.get_ref(),
@@ -79,6 +80,7 @@ pub async fn refund_retrieve_with_gateway_creds(
         _,
         types::StripeRefundResponse,
         errors::StripeErrorCode,
+        _,
     >(
         flow,
         state.get_ref(),
@@ -121,6 +123,7 @@ pub async fn refund_retrieve(
         _,
         types::StripeRefundResponse,
         errors::StripeErrorCode,
+        _,
     >(
         flow,
         state.get_ref(),
@@ -161,6 +164,7 @@ pub async fn refund_update(
         _,
         types::StripeRefundResponse,
         errors::StripeErrorCode,
+        _,
     >(
         flow,
         state.get_ref(),
diff --git a/crates/router/src/compatibility/stripe/setup_intents.rs b/crates/router/src/compatibility/stripe/setup_intents.rs
index a5d24c15810..96ef772b567 100644
--- a/crates/router/src/compatibility/stripe/setup_intents.rs
+++ b/crates/router/src/compatibility/stripe/setup_intents.rs
@@ -48,6 +48,7 @@ pub async fn setup_intents_create(
         _,
         types::StripeSetupIntentResponse,
         errors::StripeErrorCode,
+        _,
     >(
         flow,
         state.get_ref(),
@@ -105,6 +106,7 @@ pub async fn setup_intents_retrieve(
         _,
         types::StripeSetupIntentResponse,
         errors::StripeErrorCode,
+        _,
     >(
         flow,
         state.get_ref(),
@@ -168,6 +170,7 @@ pub async fn setup_intents_update(
         _,
         types::StripeSetupIntentResponse,
         errors::StripeErrorCode,
+        _,
     >(
         flow,
         state.get_ref(),
@@ -232,6 +235,7 @@ pub async fn setup_intents_confirm(
         _,
         types::StripeSetupIntentResponse,
         errors::StripeErrorCode,
+        _,
     >(
         flow,
         state.get_ref(),
diff --git a/crates/router/src/compatibility/wrap.rs b/crates/router/src/compatibility/wrap.rs
index 890c9435ede..de9926ad77e 100644
--- a/crates/router/src/compatibility/wrap.rs
+++ b/crates/router/src/compatibility/wrap.rs
@@ -1,18 +1,18 @@
 use std::{future::Future, time::Instant};
 
 use actix_web::{HttpRequest, HttpResponse, Responder};
-use common_utils::errors::ErrorSwitch;
+use common_utils::errors::{CustomResult, ErrorSwitch};
 use router_env::{instrument, tracing, Tag};
 use serde::Serialize;
 
 use crate::{
-    core::errors::{self, RouterResult},
+    core::errors::{self},
     routes::{app::AppStateInfo, metrics},
     services::{self, api, authentication as auth, logger},
 };
 
 #[instrument(skip(request, payload, state, func, api_authentication))]
-pub async fn compatibility_api_wrap<'a, 'b, A, U, T, Q, F, Fut, S, E>(
+pub async fn compatibility_api_wrap<'a, 'b, A, U, T, Q, F, Fut, S, E, E2>(
     flow: impl router_env::types::FlowMetric,
     state: &'b A,
     request: &'a HttpRequest,
@@ -22,7 +22,8 @@ pub async fn compatibility_api_wrap<'a, 'b, A, U, T, Q, F, Fut, S, E>(
 ) -> HttpResponse
 where
     F: Fn(&'b A, U, T) -> Fut,
-    Fut: Future<Output = RouterResult<api::ApplicationResponse<Q>>>,
+    Fut: Future<Output = CustomResult<api::ApplicationResponse<Q>, E2>>,
+    E2: ErrorSwitch<E> + std::error::Error + Send + Sync + 'static,
     Q: Serialize + std::fmt::Debug + 'a,
     S: TryFrom<Q> + Serialize,
     E: Serialize + error_stack::Context + actix_web::ResponseError + Clone,
diff --git a/crates/router/src/core/customers.rs b/crates/router/src/core/customers.rs
index 6fe188058b5..2397e5fdf93 100644
--- a/crates/router/src/core/customers.rs
+++ b/crates/router/src/core/customers.rs
@@ -1,4 +1,7 @@
-use common_utils::crypto::{Encryptable, GcmAes256};
+use common_utils::{
+    crypto::{Encryptable, GcmAes256},
+    errors::ReportSwitchExt,
+};
 use error_stack::ResultExt;
 use masking::ExposeInterface;
 use router_env::{instrument, tracing};
@@ -6,7 +9,7 @@ use router_env::{instrument, tracing};
 use crate::{
     consts,
     core::{
-        errors::{self, RouterResponse, StorageErrorExt},
+        errors::{self},
         payment_methods::cards,
     },
     db::StorageInterface,
@@ -32,7 +35,7 @@ pub async fn create_customer(
     merchant_account: domain::MerchantAccount,
     key_store: domain::MerchantKeyStore,
     mut customer_data: customers::CustomerRequest,
-) -> RouterResponse<customers::CustomerResponse> {
+) -> errors::CustomerResponse<customers::CustomerResponse> {
     let customer_id = &customer_data.customer_id;
     let merchant_id = &merchant_account.merchant_id;
     customer_data.merchant_id = merchant_id.to_owned();
@@ -88,12 +91,12 @@ pub async fn create_customer(
             })
         }
         .await
-        .change_context(errors::ApiErrorResponse::InternalServerError)
+        .switch()
         .attach_printable("Failed while encrypting address")?;
 
         db.insert_address(address, &key_store)
             .await
-            .change_context(errors::ApiErrorResponse::InternalServerError)
+            .switch()
             .attach_printable("Failed while inserting new address")?;
     }
 
@@ -123,7 +126,7 @@ pub async fn create_customer(
         })
     }
     .await
-    .change_context(errors::ApiErrorResponse::InternalServerError)
+    .switch()
     .attach_printable("Failed while encrypting Customer")?;
 
     let customer = match db.insert_customer(new_customer, &key_store).await {
@@ -132,13 +135,13 @@ pub async fn create_customer(
             if error.current_context().is_db_unique_violation() {
                 db.find_customer_by_customer_id_merchant_id(customer_id, merchant_id, &key_store)
                     .await
-                    .to_not_found_response(errors::ApiErrorResponse::InternalServerError)
+                    .switch()
                     .attach_printable(format!(
                         "Failed while fetching Customer, customer_id: {customer_id}",
                     ))?
             } else {
                 Err(error
-                    .change_context(errors::ApiErrorResponse::InternalServerError)
+                    .change_context(errors::CustomersErrorResponse::InternalServerError)
                     .attach_printable("Failed while inserting new customer"))?
             }
         }
@@ -155,7 +158,7 @@ pub async fn retrieve_customer(
     merchant_account: domain::MerchantAccount,
     key_store: domain::MerchantKeyStore,
     req: customers::CustomerId,
-) -> RouterResponse<customers::CustomerResponse> {
+) -> errors::CustomerResponse<customers::CustomerResponse> {
     let response = db
         .find_customer_by_customer_id_merchant_id(
             &req.customer_id,
@@ -163,7 +166,7 @@ pub async fn retrieve_customer(
             &key_store,
         )
         .await
-        .to_not_found_response(errors::ApiErrorResponse::CustomerNotFound)?;
+        .switch()?;
 
     Ok(services::ApplicationResponse::Json(response.into()))
 }
@@ -174,7 +177,7 @@ pub async fn delete_customer(
     merchant_account: domain::MerchantAccount,
     req: customers::CustomerId,
     key_store: domain::MerchantKeyStore,
-) -> RouterResponse<customers::CustomerDeleteResponse> {
+) -> errors::CustomerResponse<customers::CustomerDeleteResponse> {
     let db = &state.store;
 
     db.find_customer_by_customer_id_merchant_id(
@@ -183,16 +186,16 @@ pub async fn delete_customer(
         &key_store,
     )
     .await
-    .to_not_found_response(errors::ApiErrorResponse::CustomerNotFound)?;
+    .switch()?;
 
     let customer_mandates = db
         .find_mandate_by_merchant_id_customer_id(&merchant_account.merchant_id, &req.customer_id)
         .await
-        .to_not_found_response(errors::ApiErrorResponse::MandateNotFound)?;
+        .switch()?;
 
     for mandate in customer_mandates.into_iter() {
         if mandate.mandate_status == enums::MandateStatus::Active {
-            Err(errors::ApiErrorResponse::MandateActive)?
+            Err(errors::CustomersErrorResponse::MandateActive)?
         }
     }
 
@@ -212,14 +215,15 @@ pub async fn delete_customer(
                         &merchant_account.merchant_id,
                         &pm.payment_method_id,
                     )
-                    .await?;
+                    .await
+                    .switch()?;
                 }
                 db.delete_payment_method_by_merchant_id_payment_method_id(
                     &merchant_account.merchant_id,
                     &pm.payment_method_id,
                 )
                 .await
-                .to_not_found_response(errors::ApiErrorResponse::PaymentMethodNotFound)?;
+                .switch()?;
             }
         }
         Err(error) => {
@@ -227,7 +231,7 @@ pub async fn delete_customer(
                 Ok(())
             } else {
                 Err(error)
-                    .change_context(errors::ApiErrorResponse::InternalServerError)
+                    .change_context(errors::CustomersErrorResponse::InternalServerError)
                     .attach_printable("failed find_payment_method_by_customer_id_merchant_id_list")
             }?
         }
@@ -238,7 +242,7 @@ pub async fn delete_customer(
     let redacted_encrypted_value: Encryptable<masking::Secret<_>> =
         Encryptable::encrypt(REDACTED.to_string().into(), key, GcmAes256)
             .await
-            .change_context(errors::ApiErrorResponse::InternalServerError)?;
+            .switch()?;
 
     let update_address = storage::AddressUpdate::Update {
         city: Some(REDACTED.to_string()),
@@ -269,7 +273,7 @@ pub async fn delete_customer(
                 Ok(())
             } else {
                 Err(error)
-                    .change_context(errors::ApiErrorResponse::InternalServerError)
+                    .change_context(errors::CustomersErrorResponse::InternalServerError)
                     .attach_printable("failed update_address_by_merchant_id_customer_id")
             }
         }
@@ -280,7 +284,7 @@ pub async fn delete_customer(
         email: Some(
             Encryptable::encrypt(REDACTED.to_string().into(), key, GcmAes256)
                 .await
-                .change_context(errors::ApiErrorResponse::InternalServerError)?,
+                .switch()?,
         ),
         phone: Some(redacted_encrypted_value.clone()),
         description: Some(REDACTED.to_string()),
@@ -295,7 +299,7 @@ pub async fn delete_customer(
         &key_store,
     )
     .await
-    .change_context(errors::ApiErrorResponse::CustomerNotFound)?;
+    .switch()?;
 
     let response = customers::CustomerDeleteResponse {
         customer_id: req.customer_id,
@@ -313,7 +317,7 @@ pub async fn update_customer(
     merchant_account: domain::MerchantAccount,
     update_customer: customers::CustomerRequest,
     key_store: domain::MerchantKeyStore,
-) -> RouterResponse<customers::CustomerResponse> {
+) -> errors::CustomerResponse<customers::CustomerResponse> {
     //Add this in update call if customer can be updated anywhere else
     db.find_customer_by_customer_id_merchant_id(
         &update_customer.customer_id,
@@ -321,7 +325,7 @@ pub async fn update_customer(
         &key_store,
     )
     .await
-    .to_not_found_response(errors::ApiErrorResponse::CustomerNotFound)?;
+    .switch()?;
 
     let key = key_store.key.get_inner().peek();
 
@@ -368,7 +372,7 @@ pub async fn update_customer(
             })
         }
         .await
-        .change_context(errors::ApiErrorResponse::InternalServerError)
+        .switch()
         .attach_printable("Failed while encrypting Address while Update")?;
         db.update_address_by_merchant_id_customer_id(
             &update_customer.customer_id,
@@ -377,7 +381,7 @@ pub async fn update_customer(
             &key_store,
         )
         .await
-        .change_context(errors::ApiErrorResponse::InternalServerError)
+        .switch()
         .attach_printable(format!(
             "Failed while updating address: merchant_id: {}, customer_id: {}",
             merchant_account.merchant_id, update_customer.customer_id
@@ -411,12 +415,12 @@ pub async fn update_customer(
                 })
             }
             .await
-            .change_context(errors::ApiErrorResponse::InternalServerError)
+            .switch()
             .attach_printable("Failed while encrypting while updating customer")?,
             &key_store,
         )
         .await
-        .to_not_found_response(errors::ApiErrorResponse::CustomerNotFound)?;
+        .switch()?;
 
     let mut customer_update_response: customers::CustomerResponse = response.into();
     customer_update_response.address = update_customer.address;
diff --git a/crates/router/src/core/errors.rs b/crates/router/src/core/errors.rs
index 1e9b58ca965..2e898006da0 100644
--- a/crates/router/src/core/errors.rs
+++ b/crates/router/src/core/errors.rs
@@ -1,4 +1,5 @@
 pub mod api_error_response;
+pub mod customers_error_response;
 pub mod error_handlers;
 pub mod transformers;
 pub mod utils;
@@ -15,6 +16,7 @@ use storage_impl::errors as storage_impl_errors;
 
 pub use self::{
     api_error_response::ApiErrorResponse,
+    customers_error_response::CustomersErrorResponse,
     sch_errors::*,
     storage_errors::*,
     storage_impl_errors::*,
@@ -24,6 +26,12 @@ use crate::services;
 pub type RouterResult<T> = CustomResult<T, ApiErrorResponse>;
 pub type RouterResponse<T> = CustomResult<services::ApplicationResponse<T>, ApiErrorResponse>;
 
+pub type ApplicationResult<T> = Result<T, ApplicationError>;
+pub type ApplicationResponse<T> = ApplicationResult<services::ApplicationResponse<T>>;
+
+pub type CustomerResponse<T> =
+    CustomResult<services::ApplicationResponse<T>, CustomersErrorResponse>;
+
 macro_rules! impl_error_display {
     ($st: ident, $arg: tt) => {
         impl Display for $st {
diff --git a/crates/router/src/core/errors/customers_error_response.rs b/crates/router/src/core/errors/customers_error_response.rs
new file mode 100644
index 00000000000..b74538822e6
--- /dev/null
+++ b/crates/router/src/core/errors/customers_error_response.rs
@@ -0,0 +1,32 @@
+use http::StatusCode;
+
+#[derive(Debug, thiserror::Error)]
+pub enum CustomersErrorResponse {
+    #[error("Customer has already been redacted")]
+    CustomerRedacted,
+
+    #[error("Something went wrong")]
+    InternalServerError,
+
+    #[error("Customer has already been redacted")]
+    MandateActive,
+
+    #[error("Customer does not exist in our records")]
+    CustomerNotFound,
+}
+
+impl actix_web::ResponseError for CustomersErrorResponse {
+    fn status_code(&self) -> StatusCode {
+        common_utils::errors::ErrorSwitch::<api_models::errors::types::ApiErrorResponse>::switch(
+            self,
+        )
+        .status_code()
+    }
+
+    fn error_response(&self) -> actix_web::HttpResponse {
+        common_utils::errors::ErrorSwitch::<api_models::errors::types::ApiErrorResponse>::switch(
+            self,
+        )
+        .error_response()
+    }
+}
diff --git a/crates/router/src/core/errors/transformers.rs b/crates/router/src/core/errors/transformers.rs
index 208aad56ee1..0c78b420148 100644
--- a/crates/router/src/core/errors/transformers.rs
+++ b/crates/router/src/core/errors/transformers.rs
@@ -2,7 +2,7 @@ use api_models::errors::types::Extra;
 use common_utils::errors::ErrorSwitch;
 use http::StatusCode;
 
-use super::{ApiErrorResponse, ConnectorError};
+use super::{ApiErrorResponse, ConnectorError, CustomersErrorResponse, StorageError};
 
 impl ErrorSwitch<api_models::errors::types::ApiErrorResponse> for ApiErrorResponse {
     fn switch(&self) -> api_models::errors::types::ApiErrorResponse {
@@ -274,3 +274,61 @@ impl ErrorSwitch<ApiErrorResponse> for ConnectorError {
         }
     }
 }
+
+impl ErrorSwitch<api_models::errors::types::ApiErrorResponse> for CustomersErrorResponse {
+    fn switch(&self) -> api_models::errors::types::ApiErrorResponse {
+        use api_models::errors::types::{ApiError, ApiErrorResponse as AER};
+        match self {
+            Self::CustomerRedacted => AER::BadRequest(ApiError::new(
+                "IR",
+                11,
+                "Customer has already been redacted",
+                None,
+            )),
+            Self::InternalServerError => {
+                AER::InternalServerError(ApiError::new("HE", 0, "Something went wrong", None))
+            }
+            Self::MandateActive => AER::BadRequest(ApiError::new(
+                "IR",
+                10,
+                "Customer has active mandate/subsciption",
+                None,
+            )),
+            Self::CustomerNotFound => AER::NotFound(ApiError::new(
+                "HE",
+                2,
+                "Customer does not exist in our records",
+                None,
+            )),
+        }
+    }
+}
+
+impl ErrorSwitch<CustomersErrorResponse> for StorageError {
+    fn switch(&self) -> CustomersErrorResponse {
+        use CustomersErrorResponse as CER;
+        match self {
+            err if err.is_db_not_found() => CER::CustomerNotFound,
+            Self::CustomerRedacted => CER::CustomerRedacted,
+            _ => CER::InternalServerError,
+        }
+    }
+}
+
+impl ErrorSwitch<CustomersErrorResponse> for common_utils::errors::CryptoError {
+    fn switch(&self) -> CustomersErrorResponse {
+        CustomersErrorResponse::InternalServerError
+    }
+}
+
+impl ErrorSwitch<CustomersErrorResponse> for ApiErrorResponse {
+    fn switch(&self) -> CustomersErrorResponse {
+        use CustomersErrorResponse as CER;
+        match self {
+            Self::InternalServerError => CER::InternalServerError,
+            Self::MandateActive => CER::MandateActive,
+            Self::CustomerNotFound => CER::CustomerNotFound,
+            _ => CER::InternalServerError,
+        }
+    }
+}
diff --git a/crates/router/src/core/errors/utils.rs b/crates/router/src/core/errors/utils.rs
index f6a7bd60b12..e63471e0134 100644
--- a/crates/router/src/core/errors/utils.rs
+++ b/crates/router/src/core/errors/utils.rs
@@ -10,6 +10,37 @@ pub trait StorageErrorExt<T, E> {
     fn to_duplicate_response(self, duplicate_response: E) -> error_stack::Result<T, E>;
 }
 
+impl<T> StorageErrorExt<T, errors::CustomersErrorResponse>
+    for error_stack::Result<T, errors::StorageError>
+{
+    #[track_caller]
+    fn to_not_found_response(
+        self,
+        not_found_response: errors::CustomersErrorResponse,
+    ) -> error_stack::Result<T, errors::CustomersErrorResponse> {
+        self.map_err(|err| match err.current_context() {
+            error if error.is_db_not_found() => err.change_context(not_found_response),
+            errors::StorageError::CustomerRedacted => {
+                err.change_context(errors::CustomersErrorResponse::CustomerRedacted)
+            }
+            _ => err.change_context(errors::CustomersErrorResponse::InternalServerError),
+        })
+    }
+
+    fn to_duplicate_response(
+        self,
+        duplicate_response: errors::CustomersErrorResponse,
+    ) -> error_stack::Result<T, errors::CustomersErrorResponse> {
+        self.map_err(|err| {
+            if err.current_context().is_db_unique_violation() {
+                err.change_context(duplicate_response)
+            } else {
+                err.change_context(errors::CustomersErrorResponse::InternalServerError)
+            }
+        })
+    }
+}
+
 impl<T> StorageErrorExt<T, errors::ApiErrorResponse>
     for error_stack::Result<T, data_models::errors::StorageError>
 {

## Type of Change
<!-- Put an `x` in the boxes that apply -->

- [ ] Bugfix
- [ ] New feature
- [x] Enhancement
- [ ] Refactoring
- [ ] Dependency updates
- [ ] Documentation
- [ ] CI/CD

## Description
Have customers api endpoint specific error logging 

### Additional Changes

- [ ] This PR modifies the API contract
- [ ] This PR modifies the database schema
- [ ] This PR modifies application configuration/environment variables

<!--
Provide links to the files with corresponding changes.

Following are the paths where you can find config files:
1. `config`
2. `crates/router/src/configs`
3. `loadtest/config`
-->


## Motivation and Context
Fixes [1580](https://github.com/juspay/hyperswitch/issues/1580)


## How did you test it?
Postman


## Checklist
<!-- Put an `x` in the boxes that apply -->

- [x] I formatted the code `cargo +nightly fmt --all`
- [x] I addressed lints thrown by `cargo clippy`
- [ ] I reviewed the submitted code
- [ ] I added unit tests for my changes where possible
- [ ] I added a [CHANGELOG](/CHANGELOG.md) entry if applicable
