feat(router): add grouping and priority logic in connector utils to handle multiple errors in connector flows (#1765)

This commit is contained in:
Sai Harsha Vardhan
2023-07-26 15:47:53 +05:30
committed by GitHub
parent 9e2868ccf8
commit e6a5e9fa72

View File

@ -1096,3 +1096,132 @@ impl ForeignTryFrom<String> for CanadaStatesAbbreviation {
}
}
}
pub trait ConnectorErrorTypeMapping {
fn get_connector_error_type(
&self,
_error_code: String,
_error_message: String,
) -> ConnectorErrorType {
ConnectorErrorType::UnknownError
}
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct ErrorCodeAndMessage {
pub error_code: String,
pub error_message: String,
}
#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Debug)]
//Priority of connector_error_type
pub enum ConnectorErrorType {
UserError = 2,
BusinessError = 3,
TechnicalError = 4,
UnknownError = 1,
}
//Gets the list of error_code_and_message, sorts based on the priority of error_type and gives most prior error
// This could be used in connectors where we get list of error_messages and have to choose one error_message
pub fn get_error_code_error_message_based_on_priority(
connector: impl ConnectorErrorTypeMapping,
error_list: Vec<ErrorCodeAndMessage>,
) -> Option<ErrorCodeAndMessage> {
let error_type_list = error_list
.iter()
.map(|error| {
connector
.get_connector_error_type(error.error_code.clone(), error.error_message.clone())
})
.collect::<Vec<ConnectorErrorType>>();
let mut error_zip_list = error_list
.iter()
.zip(error_type_list.iter())
.collect::<Vec<(&ErrorCodeAndMessage, &ConnectorErrorType)>>();
error_zip_list.sort_by_key(|&(_, error_type)| error_type);
error_zip_list
.first()
.map(|&(error_code_message, _)| error_code_message)
.cloned()
}
#[cfg(test)]
mod error_code_error_message_tests {
#![allow(clippy::unwrap_used)]
use super::*;
struct TestConnector;
impl ConnectorErrorTypeMapping for TestConnector {
fn get_connector_error_type(
&self,
error_code: String,
error_message: String,
) -> ConnectorErrorType {
match (error_code.as_str(), error_message.as_str()) {
("01", "INVALID_MERCHANT") => ConnectorErrorType::BusinessError,
("03", "INVALID_CVV") => ConnectorErrorType::UserError,
("04", "04") => ConnectorErrorType::TechnicalError,
_ => ConnectorErrorType::UnknownError,
}
}
}
#[test]
fn test_get_error_code_error_message_based_on_priority() {
let error_code_message_list_unknown = vec![
ErrorCodeAndMessage {
error_code: "01".to_string(),
error_message: "INVALID_MERCHANT".to_string(),
},
ErrorCodeAndMessage {
error_code: "05".to_string(),
error_message: "05".to_string(),
},
ErrorCodeAndMessage {
error_code: "03".to_string(),
error_message: "INVALID_CVV".to_string(),
},
ErrorCodeAndMessage {
error_code: "04".to_string(),
error_message: "04".to_string(),
},
];
let error_code_message_list_user = vec![
ErrorCodeAndMessage {
error_code: "01".to_string(),
error_message: "INVALID_MERCHANT".to_string(),
},
ErrorCodeAndMessage {
error_code: "03".to_string(),
error_message: "INVALID_CVV".to_string(),
},
];
let error_code_error_message_unknown = get_error_code_error_message_based_on_priority(
TestConnector,
error_code_message_list_unknown,
);
let error_code_error_message_user = get_error_code_error_message_based_on_priority(
TestConnector,
error_code_message_list_user,
);
let error_code_error_message_none =
get_error_code_error_message_based_on_priority(TestConnector, vec![]);
assert_eq!(
error_code_error_message_unknown,
Some(ErrorCodeAndMessage {
error_code: "05".to_string(),
error_message: "05".to_string(),
})
);
assert_eq!(
error_code_error_message_user,
Some(ErrorCodeAndMessage {
error_code: "03".to_string(),
error_message: "INVALID_CVV".to_string(),
})
);
assert_eq!(error_code_error_message_none, None);
}
}