mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-10-31 01:57:45 +08:00
fix(webhook): provide acknowledgment for webhooks with unsupported event types (#1815)
This commit is contained in:
@ -1,3 +1,5 @@
|
||||
use common_utils::errors::CustomResult;
|
||||
|
||||
use crate::{core::errors, logger};
|
||||
|
||||
pub trait StorageErrorExt<T, E> {
|
||||
@ -55,6 +57,13 @@ pub trait ConnectorErrorExt<T> {
|
||||
#[cfg(feature = "payouts")]
|
||||
#[track_caller]
|
||||
fn to_payout_failed_response(self) -> error_stack::Result<T, errors::ApiErrorResponse>;
|
||||
|
||||
// Validates if the result, is Ok(..) or WebhookEventTypeNotFound all the other error variants
|
||||
// are cascaded while these two event types are handled via `Option`
|
||||
#[track_caller]
|
||||
fn allow_webhook_event_type_not_found(
|
||||
self,
|
||||
) -> error_stack::Result<Option<T>, errors::ConnectorError>;
|
||||
}
|
||||
|
||||
impl<T> ConnectorErrorExt<T> for error_stack::Result<T, errors::ConnectorError> {
|
||||
@ -230,4 +239,14 @@ impl<T> ConnectorErrorExt<T> for error_stack::Result<T, errors::ConnectorError>
|
||||
err.change_context(error)
|
||||
})
|
||||
}
|
||||
|
||||
fn allow_webhook_event_type_not_found(self) -> CustomResult<Option<T>, errors::ConnectorError> {
|
||||
match self {
|
||||
Ok(event_type) => Ok(Some(event_type)),
|
||||
Err(error) => match error.current_context() {
|
||||
errors::ConnectorError::WebhookEventTypeNotFound => Ok(None),
|
||||
_ => Err(error),
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -39,3 +39,7 @@ counter_metric!(WEBHOOK_SOURCE_VERIFIED_COUNT, GLOBAL_METER);
|
||||
counter_metric!(WEBHOOK_OUTGOING_COUNT, GLOBAL_METER);
|
||||
counter_metric!(WEBHOOK_OUTGOING_RECEIVED_COUNT, GLOBAL_METER);
|
||||
counter_metric!(WEBHOOK_OUTGOING_NOT_RECEIVED_COUNT, GLOBAL_METER);
|
||||
counter_metric!(
|
||||
WEBHOOK_EVENT_TYPE_IDENTIFICATION_FAILURE_COUNT,
|
||||
GLOBAL_METER
|
||||
);
|
||||
|
||||
@ -10,7 +10,7 @@ use super::{errors::StorageErrorExt, metrics};
|
||||
use crate::{
|
||||
consts,
|
||||
core::{
|
||||
errors::{self, CustomResult, RouterResponse},
|
||||
errors::{self, ConnectorErrorExt, CustomResult, RouterResponse},
|
||||
payments, refunds,
|
||||
},
|
||||
logger,
|
||||
@ -672,10 +672,35 @@ pub async fn webhooks_core<W: types::OutgoingWebhookType>(
|
||||
|
||||
request_details.body = &decoded_body;
|
||||
|
||||
let event_type = connector
|
||||
let event_type = match connector
|
||||
.get_webhook_event_type(&request_details)
|
||||
.allow_webhook_event_type_not_found()
|
||||
.switch()
|
||||
.attach_printable("Could not find event type in incoming webhook body")?;
|
||||
.attach_printable("Could not find event type in incoming webhook body")?
|
||||
{
|
||||
Some(event_type) => event_type,
|
||||
// Early return allows us to acknowledge the webhooks that we do not support
|
||||
None => {
|
||||
logger::error!(
|
||||
webhook_payload =? request_details.body,
|
||||
"Failed while identifying the event type",
|
||||
);
|
||||
|
||||
metrics::WEBHOOK_EVENT_TYPE_IDENTIFICATION_FAILURE_COUNT.add(
|
||||
&metrics::CONTEXT,
|
||||
1,
|
||||
&[
|
||||
metrics::KeyValue::new(MERCHANT_ID, merchant_account.merchant_id.clone()),
|
||||
metrics::KeyValue::new("connector", connector_name.to_string()),
|
||||
],
|
||||
);
|
||||
|
||||
return connector
|
||||
.get_webhook_api_response(&request_details)
|
||||
.switch()
|
||||
.attach_printable("Failed while early return in case of event type parsing");
|
||||
}
|
||||
};
|
||||
|
||||
let process_webhook_further = utils::lookup_webhook_event(
|
||||
&*state.store,
|
||||
|
||||
Reference in New Issue
Block a user