fix(webhook): provide acknowledgment for webhooks with unsupported event types (#1815)

This commit is contained in:
Nishant Joshi
2023-07-31 13:02:12 +05:30
committed by GitHub
parent fc774d0c05
commit 28a371b24a
3 changed files with 51 additions and 3 deletions

View File

@ -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),
},
}
}
}

View File

@ -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
);

View File

@ -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,