mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-11-01 11:06:50 +08:00
refactor: include api key expiry workflow into process tracker (#3661)
This commit is contained in:
@ -138,7 +138,7 @@ mod diesel_impl {
|
|||||||
|
|
||||||
// Tracking data by process_tracker
|
// Tracking data by process_tracker
|
||||||
#[derive(Default, Debug, Deserialize, Serialize, Clone)]
|
#[derive(Default, Debug, Deserialize, Serialize, Clone)]
|
||||||
pub struct ApiKeyExpiryWorkflow {
|
pub struct ApiKeyExpiryTrackingData {
|
||||||
pub key_id: String,
|
pub key_id: String,
|
||||||
pub merchant_id: String,
|
pub merchant_id: String,
|
||||||
pub api_key_expiry: Option<PrimitiveDateTime>,
|
pub api_key_expiry: Option<PrimitiveDateTime>,
|
||||||
|
|||||||
@ -13,7 +13,7 @@ default = ["kv_store", "stripe", "oltp", "olap", "backwards_compatibility", "acc
|
|||||||
aws_s3 = ["external_services/aws_s3"]
|
aws_s3 = ["external_services/aws_s3"]
|
||||||
aws_kms = ["external_services/aws_kms"]
|
aws_kms = ["external_services/aws_kms"]
|
||||||
hashicorp-vault = ["external_services/hashicorp-vault"]
|
hashicorp-vault = ["external_services/hashicorp-vault"]
|
||||||
email = ["external_services/email", "olap"]
|
email = ["external_services/email", "scheduler/email", "olap"]
|
||||||
frm = []
|
frm = []
|
||||||
stripe = ["dep:serde_qs"]
|
stripe = ["dep:serde_qs"]
|
||||||
release = ["aws_kms", "stripe", "aws_s3", "email", "backwards_compatibility", "business_profile_routing", "accounts_cache", "kv_store", "connector_choice_mca_id", "profile_specific_fallback_routing", "vergen", "recon"]
|
release = ["aws_kms", "stripe", "aws_s3", "email", "backwards_compatibility", "business_profile_routing", "accounts_cache", "kv_store", "connector_choice_mca_id", "profile_specific_fallback_routing", "vergen", "recon"]
|
||||||
|
|||||||
@ -216,6 +216,8 @@ pub enum PTRunner {
|
|||||||
PaymentsSyncWorkflow,
|
PaymentsSyncWorkflow,
|
||||||
RefundWorkflowRouter,
|
RefundWorkflowRouter,
|
||||||
DeleteTokenizeDataWorkflow,
|
DeleteTokenizeDataWorkflow,
|
||||||
|
#[cfg(feature = "email")]
|
||||||
|
ApiKeyExpiryWorkflow,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone)]
|
#[derive(Debug, Copy, Clone)]
|
||||||
@ -240,6 +242,10 @@ impl ProcessTrackerWorkflows<routes::AppState> for WorkflowRunner {
|
|||||||
Some(PTRunner::DeleteTokenizeDataWorkflow) => {
|
Some(PTRunner::DeleteTokenizeDataWorkflow) => {
|
||||||
Box::new(workflows::tokenized_data::DeleteTokenizeDataWorkflow)
|
Box::new(workflows::tokenized_data::DeleteTokenizeDataWorkflow)
|
||||||
}
|
}
|
||||||
|
#[cfg(feature = "email")]
|
||||||
|
Some(PTRunner::ApiKeyExpiryWorkflow) => {
|
||||||
|
Box::new(workflows::api_key_expiry::ApiKeyExpiryWorkflow)
|
||||||
|
}
|
||||||
_ => Err(ProcessTrackerError::UnexpectedFlow)?,
|
_ => Err(ProcessTrackerError::UnexpectedFlow)?,
|
||||||
};
|
};
|
||||||
let app_state = &state.clone();
|
let app_state = &state.clone();
|
||||||
|
|||||||
@ -253,7 +253,7 @@ pub async fn add_api_key_expiry_task(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let api_key_expiry_tracker = &storage::ApiKeyExpiryWorkflow {
|
let api_key_expiry_tracker = &storage::ApiKeyExpiryTrackingData {
|
||||||
key_id: api_key.key_id.clone(),
|
key_id: api_key.key_id.clone(),
|
||||||
merchant_id: api_key.merchant_id.clone(),
|
merchant_id: api_key.merchant_id.clone(),
|
||||||
// We need API key expiry too, because we need to decide on the schedule_time in
|
// We need API key expiry too, because we need to decide on the schedule_time in
|
||||||
@ -427,7 +427,7 @@ pub async fn update_api_key_expiry_task(
|
|||||||
|
|
||||||
let task_ids = vec![task_id.clone()];
|
let task_ids = vec![task_id.clone()];
|
||||||
|
|
||||||
let updated_tracking_data = &storage::ApiKeyExpiryWorkflow {
|
let updated_tracking_data = &storage::ApiKeyExpiryTrackingData {
|
||||||
key_id: api_key.key_id.clone(),
|
key_id: api_key.key_id.clone(),
|
||||||
merchant_id: api_key.merchant_id.clone(),
|
merchant_id: api_key.merchant_id.clone(),
|
||||||
api_key_expiry: api_key.expires_at,
|
api_key_expiry: api_key.expires_at,
|
||||||
|
|||||||
@ -0,0 +1,203 @@
|
|||||||
|
<meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
|
||||||
|
<title>API Key Expiry Notice</title>
|
||||||
|
<body style="background-color: #ececec">
|
||||||
|
<style>
|
||||||
|
.apple-footer a {{
|
||||||
|
text-decoration: none !important;
|
||||||
|
color: #999 !important;
|
||||||
|
border: none !important;
|
||||||
|
}}
|
||||||
|
.apple-email a {{
|
||||||
|
text-decoration: none !important;
|
||||||
|
color: #448bff !important;
|
||||||
|
border: none !important;
|
||||||
|
}}
|
||||||
|
</style>
|
||||||
|
<div
|
||||||
|
id="wrapper"
|
||||||
|
style="
|
||||||
|
background-color: none;
|
||||||
|
margin: 0 auto;
|
||||||
|
text-align: center;
|
||||||
|
width: 60%;
|
||||||
|
-premailer-height: 200;
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<table
|
||||||
|
align="center"
|
||||||
|
class="main-table"
|
||||||
|
style="
|
||||||
|
-premailer-cellpadding: 0;
|
||||||
|
-premailer-cellspacing: 0;
|
||||||
|
background-color: #fff;
|
||||||
|
border: 0;
|
||||||
|
border-top: 5px solid #0165ef;
|
||||||
|
margin: 0 auto;
|
||||||
|
mso-table-lspace: 0;
|
||||||
|
mso-table-rspace: 0;
|
||||||
|
padding: 0 40;
|
||||||
|
text-align: center;
|
||||||
|
width: 100%;
|
||||||
|
"
|
||||||
|
bgcolor="#ffffff"
|
||||||
|
cellpadding="0"
|
||||||
|
cellspacing="0"
|
||||||
|
>
|
||||||
|
<tr>
|
||||||
|
<td
|
||||||
|
class="spacer-lg"
|
||||||
|
style="
|
||||||
|
-premailer-height: 75;
|
||||||
|
-premailer-width: 100%;
|
||||||
|
line-height: 30px;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 0;
|
||||||
|
"
|
||||||
|
height="75"
|
||||||
|
width="100%"
|
||||||
|
></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td
|
||||||
|
class="spacer-lg"
|
||||||
|
style="
|
||||||
|
-premailer-height: 75;
|
||||||
|
-premailer-width: 100%;
|
||||||
|
line-height: 30px;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 0;
|
||||||
|
"
|
||||||
|
height="25"
|
||||||
|
width="100%"
|
||||||
|
></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td
|
||||||
|
class="spacer-lg"
|
||||||
|
style="
|
||||||
|
-premailer-height: 75;
|
||||||
|
-premailer-width: 100%;
|
||||||
|
line-height: 30px;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 0;
|
||||||
|
"
|
||||||
|
height="50"
|
||||||
|
width="100%"
|
||||||
|
></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td
|
||||||
|
class="headline"
|
||||||
|
style="
|
||||||
|
color: #444;
|
||||||
|
font-family: Roboto, Helvetica, Arial, san-serif;
|
||||||
|
font-size: 30px;
|
||||||
|
font-weight: 100;
|
||||||
|
line-height: 36px;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 0;
|
||||||
|
text-align: center;
|
||||||
|
"
|
||||||
|
align="center"
|
||||||
|
>
|
||||||
|
<p style="font-size: 18px">Dear Merchant,</p>
|
||||||
|
<span style="font-size: 18px">
|
||||||
|
It has come to our attention that your API key will expire in {expires_in} days. To ensure uninterrupted
|
||||||
|
access to our platform and continued smooth operation of your services, we kindly request that you take the
|
||||||
|
necessary actions as soon as possible.
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td
|
||||||
|
class="spacer-sm"
|
||||||
|
style="
|
||||||
|
-premailer-height: 20;
|
||||||
|
-premailer-width: 80%;
|
||||||
|
line-height: 10px;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 0;
|
||||||
|
"
|
||||||
|
width="100%"
|
||||||
|
></td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td
|
||||||
|
class="spacer-sm"
|
||||||
|
style="
|
||||||
|
-premailer-height: 20;
|
||||||
|
-premailer-width: 100%;
|
||||||
|
line-height: 10px;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 0;
|
||||||
|
"
|
||||||
|
height="20"
|
||||||
|
width="100%"
|
||||||
|
></td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td
|
||||||
|
class="spacer-lg"
|
||||||
|
style="
|
||||||
|
-premailer-height: 75;
|
||||||
|
-premailer-width: 100%;
|
||||||
|
line-height: 30px;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 0;
|
||||||
|
"
|
||||||
|
height="75"
|
||||||
|
width="100%"
|
||||||
|
></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td
|
||||||
|
class="headline"
|
||||||
|
style="
|
||||||
|
color: #444;
|
||||||
|
font-family: Roboto, Helvetica, Arial, san-serif;
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: 100;
|
||||||
|
line-height: 36px;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 0;
|
||||||
|
text-align: center;
|
||||||
|
"
|
||||||
|
align="center"
|
||||||
|
>
|
||||||
|
Thanks,<br />
|
||||||
|
Team Hyperswitch
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td
|
||||||
|
class="spacer-lg"
|
||||||
|
style="
|
||||||
|
-premailer-height: 75;
|
||||||
|
-premailer-width: 100%;
|
||||||
|
line-height: 30px;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 0;
|
||||||
|
"
|
||||||
|
height="75"
|
||||||
|
width="100%"
|
||||||
|
></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td
|
||||||
|
class="spacer-lg"
|
||||||
|
style="
|
||||||
|
-premailer-height: 75;
|
||||||
|
-premailer-width: 100%;
|
||||||
|
line-height: 30px;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 0;
|
||||||
|
"
|
||||||
|
height="75"
|
||||||
|
width="100%"
|
||||||
|
></td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
@ -44,6 +44,9 @@ pub enum EmailBody {
|
|||||||
user_name: String,
|
user_name: String,
|
||||||
user_email: String,
|
user_email: String,
|
||||||
},
|
},
|
||||||
|
ApiKeyExpiryReminder {
|
||||||
|
expires_in: u8,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
pub mod html {
|
pub mod html {
|
||||||
@ -113,6 +116,10 @@ Email : {user_email}
|
|||||||
|
|
||||||
(note: This is an auto generated email. Use merchant email for any further communications)",
|
(note: This is an auto generated email. Use merchant email for any further communications)",
|
||||||
),
|
),
|
||||||
|
EmailBody::ApiKeyExpiryReminder { expires_in } => format!(
|
||||||
|
include_str!("assets/api_key_expiry_reminder.html"),
|
||||||
|
expires_in = expires_in,
|
||||||
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -381,3 +388,26 @@ impl EmailData for ProFeatureRequest {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct ApiKeyExpiryReminder {
|
||||||
|
pub recipient_email: domain::UserEmail,
|
||||||
|
pub subject: &'static str,
|
||||||
|
pub expires_in: u8,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[async_trait::async_trait]
|
||||||
|
impl EmailData for ApiKeyExpiryReminder {
|
||||||
|
async fn get_email_data(&self) -> CustomResult<EmailContents, EmailError> {
|
||||||
|
let recipient = self.recipient_email.clone().into_inner();
|
||||||
|
|
||||||
|
let body = html::get_html_body(EmailBody::ApiKeyExpiryReminder {
|
||||||
|
expires_in: self.expires_in,
|
||||||
|
});
|
||||||
|
|
||||||
|
Ok(EmailContents {
|
||||||
|
subject: self.subject.to_string(),
|
||||||
|
body: external_services::email::IntermediateString::new(body),
|
||||||
|
recipient,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -1,3 +1,3 @@
|
|||||||
#[cfg(feature = "email")]
|
#[cfg(feature = "email")]
|
||||||
pub use diesel_models::api_keys::ApiKeyExpiryWorkflow;
|
pub use diesel_models::api_keys::ApiKeyExpiryTrackingData;
|
||||||
pub use diesel_models::api_keys::{ApiKey, ApiKeyNew, ApiKeyUpdate, HashedApiKey};
|
pub use diesel_models::api_keys::{ApiKey, ApiKeyNew, ApiKeyUpdate, HashedApiKey};
|
||||||
|
|||||||
@ -1,3 +1,5 @@
|
|||||||
|
#[cfg(feature = "email")]
|
||||||
|
pub mod api_key_expiry;
|
||||||
pub mod payment_sync;
|
pub mod payment_sync;
|
||||||
pub mod refund_router;
|
pub mod refund_router;
|
||||||
pub mod tokenized_data;
|
pub mod tokenized_data;
|
||||||
|
|||||||
@ -1,30 +1,35 @@
|
|||||||
use common_utils::ext_traits::ValueExt;
|
use common_utils::{errors::ValidationError, ext_traits::ValueExt};
|
||||||
use diesel_models::enums::{self as storage_enums};
|
use diesel_models::{enums as storage_enums, ApiKeyExpiryTrackingData};
|
||||||
|
use router_env::logger;
|
||||||
|
use scheduler::{workflows::ProcessTrackerWorkflow, SchedulerAppState};
|
||||||
|
|
||||||
use super::{ApiKeyExpiryWorkflow, ProcessTrackerWorkflow};
|
|
||||||
use crate::{
|
use crate::{
|
||||||
errors,
|
errors,
|
||||||
logger::error,
|
logger::error,
|
||||||
routes::AppState,
|
routes::{metrics, AppState},
|
||||||
|
services::email::types::ApiKeyExpiryReminder,
|
||||||
types::{
|
types::{
|
||||||
api,
|
api,
|
||||||
|
domain::UserEmail,
|
||||||
storage::{self, ProcessTrackerExt},
|
storage::{self, ProcessTrackerExt},
|
||||||
},
|
},
|
||||||
utils::OptionExt,
|
utils::OptionExt,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub struct ApiKeyExpiryWorkflow;
|
||||||
|
|
||||||
#[async_trait::async_trait]
|
#[async_trait::async_trait]
|
||||||
impl ProcessTrackerWorkflow for ApiKeyExpiryWorkflow {
|
impl ProcessTrackerWorkflow<AppState> for ApiKeyExpiryWorkflow {
|
||||||
async fn execute_workflow<'a>(
|
async fn execute_workflow<'a>(
|
||||||
&'a self,
|
&'a self,
|
||||||
state: &'a AppState,
|
state: &'a AppState,
|
||||||
process: storage::ProcessTracker,
|
process: storage::ProcessTracker,
|
||||||
) -> Result<(), errors::ProcessTrackerError> {
|
) -> Result<(), errors::ProcessTrackerError> {
|
||||||
let db = &*state.store;
|
let db = &*state.store;
|
||||||
let tracking_data: storage::ApiKeyExpiryWorkflow = process
|
let tracking_data: ApiKeyExpiryTrackingData = process
|
||||||
.tracking_data
|
.tracking_data
|
||||||
.clone()
|
.clone()
|
||||||
.parse_value("ApiKeyExpiryWorkflow")?;
|
.parse_value("ApiKeyExpiryTrackingData")?;
|
||||||
|
|
||||||
let key_store = state
|
let key_store = state
|
||||||
.store
|
.store
|
||||||
@ -41,7 +46,13 @@ impl ProcessTrackerWorkflow for ApiKeyExpiryWorkflow {
|
|||||||
let email_id = merchant_account
|
let email_id = merchant_account
|
||||||
.merchant_details
|
.merchant_details
|
||||||
.parse_value::<api::MerchantDetails>("MerchantDetails")?
|
.parse_value::<api::MerchantDetails>("MerchantDetails")?
|
||||||
.primary_email;
|
.primary_email
|
||||||
|
.ok_or(errors::ProcessTrackerError::EValidationError(
|
||||||
|
ValidationError::MissingRequiredField {
|
||||||
|
field_name: "email".to_string(),
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
|
))?;
|
||||||
|
|
||||||
let task_id = process.id.clone();
|
let task_id = process.id.clone();
|
||||||
|
|
||||||
@ -53,28 +64,26 @@ impl ProcessTrackerWorkflow for ApiKeyExpiryWorkflow {
|
|||||||
usize::try_from(retry_count)
|
usize::try_from(retry_count)
|
||||||
.map_err(|_| errors::ProcessTrackerError::TypeConversionError)?,
|
.map_err(|_| errors::ProcessTrackerError::TypeConversionError)?,
|
||||||
)
|
)
|
||||||
.ok_or(errors::ProcessTrackerError::EApiErrorResponse(
|
.ok_or(errors::ProcessTrackerError::EApiErrorResponse)?;
|
||||||
errors::ApiErrorResponse::InvalidDataValue {
|
|
||||||
field_name: "index",
|
let email_contents = ApiKeyExpiryReminder {
|
||||||
}
|
recipient_email: UserEmail::from_pii_email(email_id).map_err(|err| {
|
||||||
.into(),
|
logger::error!(%err,"Failed to convert recipient's email to UserEmail from pii::Email");
|
||||||
))?;
|
errors::ProcessTrackerError::EApiErrorResponse
|
||||||
|
})?,
|
||||||
|
subject: "API Key Expiry Notice",
|
||||||
|
expires_in: *expires_in,
|
||||||
|
};
|
||||||
|
|
||||||
state
|
state
|
||||||
.email_client
|
.email_client
|
||||||
.clone()
|
.clone()
|
||||||
.send_email(
|
.compose_and_send_email(
|
||||||
email_id.ok_or_else(|| errors::ProcessTrackerError::MissingRequiredField)?,
|
Box::new(email_contents),
|
||||||
"API Key Expiry Notice".to_string(),
|
state.conf.proxy.https_url.as_ref(),
|
||||||
format!("Dear Merchant,\n
|
|
||||||
It has come to our attention that your API key will expire in {expires_in} days. To ensure uninterrupted access to our platform and continued smooth operation of your services, we kindly request that you take the necessary actions as soon as possible.\n\n
|
|
||||||
Thanks,\n
|
|
||||||
Team Hyperswitch"),
|
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
.map_err(|_| errors::ProcessTrackerError::FlowExecutionError {
|
.map_err(errors::ProcessTrackerError::EEmailError)?;
|
||||||
flow: "ApiKeyExpiryWorkflow",
|
|
||||||
})?;
|
|
||||||
|
|
||||||
// If all the mails have been sent, then retry_count would be equal to length of the expiry_reminder_days vector
|
// If all the mails have been sent, then retry_count would be equal to length of the expiry_reminder_days vector
|
||||||
if retry_count
|
if retry_count
|
||||||
@ -82,7 +91,7 @@ Team Hyperswitch"),
|
|||||||
.map_err(|_| errors::ProcessTrackerError::TypeConversionError)?
|
.map_err(|_| errors::ProcessTrackerError::TypeConversionError)?
|
||||||
{
|
{
|
||||||
process
|
process
|
||||||
.finish_with_status(db, format!("COMPLETED_BY_PT_{task_id}"))
|
.finish_with_status(state.get_db().as_scheduler(), "COMPLETED_BY_PT".to_string())
|
||||||
.await?
|
.await?
|
||||||
}
|
}
|
||||||
// If tasks are remaining that has to be scheduled
|
// If tasks are remaining that has to be scheduled
|
||||||
@ -93,12 +102,7 @@ Team Hyperswitch"),
|
|||||||
usize::try_from(retry_count + 1)
|
usize::try_from(retry_count + 1)
|
||||||
.map_err(|_| errors::ProcessTrackerError::TypeConversionError)?,
|
.map_err(|_| errors::ProcessTrackerError::TypeConversionError)?,
|
||||||
)
|
)
|
||||||
.ok_or(errors::ProcessTrackerError::EApiErrorResponse(
|
.ok_or(errors::ProcessTrackerError::EApiErrorResponse)?;
|
||||||
errors::ApiErrorResponse::InvalidDataValue {
|
|
||||||
field_name: "index",
|
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
))?;
|
|
||||||
|
|
||||||
let updated_schedule_time = tracking_data.api_key_expiry.map(|api_key_expiry| {
|
let updated_schedule_time = tracking_data.api_key_expiry.map(|api_key_expiry| {
|
||||||
api_key_expiry.saturating_sub(time::Duration::days(i64::from(*expiry_reminder_day)))
|
api_key_expiry.saturating_sub(time::Duration::days(i64::from(*expiry_reminder_day)))
|
||||||
|
|||||||
@ -7,6 +7,7 @@ edition = "2021"
|
|||||||
default = ["kv_store", "olap"]
|
default = ["kv_store", "olap"]
|
||||||
olap = ["storage_impl/olap"]
|
olap = ["storage_impl/olap"]
|
||||||
kv_store = []
|
kv_store = []
|
||||||
|
email = ["external_services/email"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
# Third party crates
|
# Third party crates
|
||||||
|
|||||||
@ -1,4 +1,6 @@
|
|||||||
pub use common_utils::errors::{ParsingError, ValidationError};
|
pub use common_utils::errors::{ParsingError, ValidationError};
|
||||||
|
#[cfg(feature = "email")]
|
||||||
|
use external_services::email::EmailError;
|
||||||
pub use redis_interface::errors::RedisError;
|
pub use redis_interface::errors::RedisError;
|
||||||
pub use storage_impl::errors::ApplicationError;
|
pub use storage_impl::errors::ApplicationError;
|
||||||
use storage_impl::errors::StorageError;
|
use storage_impl::errors::StorageError;
|
||||||
@ -51,6 +53,9 @@ pub enum ProcessTrackerError {
|
|||||||
EParsingError(error_stack::Report<ParsingError>),
|
EParsingError(error_stack::Report<ParsingError>),
|
||||||
#[error("Validation Error Received: {0}")]
|
#[error("Validation Error Received: {0}")]
|
||||||
EValidationError(error_stack::Report<ValidationError>),
|
EValidationError(error_stack::Report<ValidationError>),
|
||||||
|
#[cfg(feature = "email")]
|
||||||
|
#[error("Received Error EmailError: {0}")]
|
||||||
|
EEmailError(error_stack::Report<EmailError>),
|
||||||
#[error("Type Conversion error")]
|
#[error("Type Conversion error")]
|
||||||
TypeConversionError,
|
TypeConversionError,
|
||||||
}
|
}
|
||||||
@ -111,3 +116,9 @@ error_to_process_tracker_error!(
|
|||||||
error_stack::Report<ValidationError>,
|
error_stack::Report<ValidationError>,
|
||||||
ProcessTrackerError::EValidationError(error_stack::Report<ValidationError>)
|
ProcessTrackerError::EValidationError(error_stack::Report<ValidationError>)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
#[cfg(feature = "email")]
|
||||||
|
error_to_process_tracker_error!(
|
||||||
|
error_stack::Report<EmailError>,
|
||||||
|
ProcessTrackerError::EEmailError(error_stack::Report<EmailError>)
|
||||||
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user