Skip to content

Commit

Permalink
refactor: refactor connector auth type failure to 4xx (#2616)
Browse files Browse the repository at this point in the history
  • Loading branch information
ArjunKarthik authored Oct 18, 2023
1 parent 73e9391 commit 1dad745
Show file tree
Hide file tree
Showing 7 changed files with 125 additions and 20 deletions.
8 changes: 7 additions & 1 deletion crates/router/src/compatibility/stripe/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,8 @@ pub enum StripeErrorCode {
PaymentLinkNotFound,
#[error(error_type = StripeErrorType::HyperswitchError, code = "", message = "Resource Busy. Please try again later")]
LockTimeout,
#[error(error_type = StripeErrorType::InvalidRequestError, code = "", message = "Merchant connector account is configured with invalid {config}")]
InvalidConnectorConfiguration { config: String },
// [#216]: https://github.com/juspay/hyperswitch/issues/216
// Implement the remaining stripe error codes

Expand Down Expand Up @@ -590,6 +592,9 @@ impl From<errors::ApiErrorResponse> for StripeErrorCode {
Self::PaymentMethodUnactivated
}
errors::ApiErrorResponse::ResourceBusy => Self::PaymentMethodUnactivated,
errors::ApiErrorResponse::InvalidConnectorConfiguration { config } => {
Self::InvalidConnectorConfiguration { config }
}
}
}
}
Expand Down Expand Up @@ -656,7 +661,8 @@ impl actix_web::ResponseError for StripeErrorCode {
| Self::FileProviderNotSupported
| Self::CurrencyNotSupported { .. }
| Self::DuplicateCustomer
| Self::PaymentMethodUnactivated => StatusCode::BAD_REQUEST,
| Self::PaymentMethodUnactivated
| Self::InvalidConnectorConfiguration { .. } => StatusCode::BAD_REQUEST,
Self::RefundFailed
| Self::PayoutFailed
| Self::PaymentLinkNotFound
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,8 @@ impl TryFrom<&Option<pii::SecretSerdeValue>> for BraintreeMeta {
type Error = error_stack::Report<errors::ConnectorError>;
fn try_from(meta_data: &Option<pii::SecretSerdeValue>) -> Result<Self, Self::Error> {
let metadata: Self = utils::to_connector_meta_from_secret::<Self>(meta_data.clone())
.change_context(errors::ConnectorError::InvalidConfig {
field_name: "merchant connector account metadata",
.change_context(errors::ConnectorError::InvalidConnectorConfig {
config: "metadata",
})?;
Ok(metadata)
}
Expand All @@ -109,8 +109,8 @@ impl TryFrom<&BraintreeRouterData<&types::PaymentsAuthorizeRouterData>>
) -> Result<Self, Self::Error> {
let metadata: BraintreeMeta =
utils::to_connector_meta_from_secret(item.router_data.connector_meta_data.clone())
.change_context(errors::ConnectorError::InvalidConfig {
field_name: "merchant connector account metadata",
.change_context(errors::ConnectorError::InvalidConnectorConfig {
config: "metadata",
})?;
utils::validate_currency(
item.router_data.request.currency,
Expand Down Expand Up @@ -602,8 +602,8 @@ impl<F> TryFrom<BraintreeRouterData<&types::RefundsRouterData<F>>> for Braintree
) -> Result<Self, Self::Error> {
let metadata: BraintreeMeta =
utils::to_connector_meta_from_secret(item.router_data.connector_meta_data.clone())
.change_context(errors::ConnectorError::InvalidConfig {
field_name: "merchant connector account metadata",
.change_context(errors::ConnectorError::InvalidConnectorConfig {
config: "metadata",
})?;

utils::validate_currency(
Expand Down Expand Up @@ -712,9 +712,7 @@ impl TryFrom<&types::RefundSyncRouterData> for BraintreeRSyncRequest {
let metadata: BraintreeMeta = utils::to_connector_meta_from_secret(
item.connector_meta_data.clone(),
)
.change_context(errors::ConnectorError::InvalidConfig {
field_name: "merchant connector account metadata",
})?;
.change_context(errors::ConnectorError::InvalidConnectorConfig { config: "metadata" })?;
utils::validate_currency(
item.request.currency,
Some(metadata.merchant_config_currency),
Expand Down Expand Up @@ -1345,8 +1343,8 @@ impl TryFrom<&BraintreeRouterData<&types::PaymentsCompleteAuthorizeRouterData>>
) -> Result<Self, Self::Error> {
let metadata: BraintreeMeta =
utils::to_connector_meta_from_secret(item.router_data.connector_meta_data.clone())
.change_context(errors::ConnectorError::InvalidConfig {
field_name: "merchant connector account metadata",
.change_context(errors::ConnectorError::InvalidConnectorConfig {
config: "metadata",
})?;
utils::validate_currency(
item.router_data.request.currency,
Expand Down
7 changes: 3 additions & 4 deletions crates/router/src/core/admin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -701,11 +701,10 @@ pub async fn create_payment_connector(
message: "The connector name is invalid".to_string(),
})
}
errors::ConnectorError::InvalidConfig { field_name } => {
err.change_context(errors::ApiErrorResponse::InvalidRequestData {
errors::ConnectorError::InvalidConnectorConfig { config: field_name } => err
.change_context(errors::ApiErrorResponse::InvalidRequestData {
message: format!("The {} is invalid", field_name),
})
}
}),
errors::ConnectorError::FailedToObtainAuthType => {
err.change_context(errors::ApiErrorResponse::InvalidRequestData {
message: "The auth type is invalid for the connector".to_string(),
Expand Down
2 changes: 1 addition & 1 deletion crates/router/src/core/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ pub enum ConnectorError {
connector: &'static str,
},
#[error("Invalid Configuration")]
InvalidConfig { field_name: &'static str },
InvalidConnectorConfig { config: &'static str },
}

#[derive(Debug, thiserror::Error)]
Expand Down
2 changes: 2 additions & 0 deletions crates/router/src/core/errors/api_error_response.rs
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,8 @@ pub enum ApiErrorResponse {
WebhookInvalidMerchantSecret,
#[error(error_type = ErrorType::InvalidRequestError, code = "IR_19", message = "{message}")]
CurrencyNotSupported { message: String },
#[error(error_type = ErrorType::InvalidRequestError, code = "IR_24", message = "Merchant connector account is configured with invalid {config}")]
InvalidConnectorConfiguration { config: String },
}

impl PTError for ApiErrorResponse {
Expand Down
3 changes: 3 additions & 0 deletions crates/router/src/core/errors/transformers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,9 @@ impl ErrorSwitch<api_models::errors::types::ApiErrorResponse> for ApiErrorRespon
Self::PaymentLinkNotFound => {
AER::NotFound(ApiError::new("HE", 2, "Payment Link does not exist in our records", None))
}
Self::InvalidConnectorConfiguration {config} => {
AER::BadRequest(ApiError::new("IR", 24, format!("Merchant connector account is configured with invalid {config}"), None))
}
}
}
}
Expand Down
103 changes: 100 additions & 3 deletions crates/router/src/core/errors/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,48 @@ impl<T> ConnectorErrorExt<T> for error_stack::Result<T, errors::ConnectorError>
errors::ApiErrorResponse::InvalidDataValue { field_name }
},
errors::ConnectorError::CurrencyNotSupported { message, connector} => errors::ApiErrorResponse::CurrencyNotSupported { message: format!("Credentials for the currency {message} are not configured with the connector {connector}/hyperswitch") },
_ => errors::ApiErrorResponse::InternalServerError,
errors::ConnectorError::FailedToObtainAuthType => errors::ApiErrorResponse::InvalidConnectorConfiguration {config: "connector_account_details".to_string()},
errors::ConnectorError::InvalidConnectorConfig { config } => errors::ApiErrorResponse::InvalidConnectorConfiguration { config: config.to_string() },
errors::ConnectorError::FailedToObtainIntegrationUrl |
errors::ConnectorError::RequestEncodingFailed |
errors::ConnectorError::RequestEncodingFailedWithReason(_) |
errors::ConnectorError::ParsingFailed |
errors::ConnectorError::ResponseDeserializationFailed |
errors::ConnectorError::UnexpectedResponseError(_) |
errors::ConnectorError::RoutingRulesParsingError |
errors::ConnectorError::FailedToObtainPreferredConnector |
errors::ConnectorError::InvalidConnectorName |
errors::ConnectorError::InvalidWallet |
errors::ConnectorError::ResponseHandlingFailed |
errors::ConnectorError::FailedToObtainCertificate |
errors::ConnectorError::NoConnectorMetaData |
errors::ConnectorError::FailedToObtainCertificateKey |
errors::ConnectorError::CaptureMethodNotSupported |
errors::ConnectorError::MissingConnectorMandateID |
errors::ConnectorError::MissingConnectorTransactionID |
errors::ConnectorError::MissingConnectorRefundID |
errors::ConnectorError::MissingApplePayTokenData |
errors::ConnectorError::WebhooksNotImplemented |
errors::ConnectorError::WebhookBodyDecodingFailed |
errors::ConnectorError::WebhookSignatureNotFound |
errors::ConnectorError::WebhookSourceVerificationFailed |
errors::ConnectorError::WebhookVerificationSecretNotFound |
errors::ConnectorError::WebhookVerificationSecretInvalid |
errors::ConnectorError::WebhookReferenceIdNotFound |
errors::ConnectorError::WebhookEventTypeNotFound |
errors::ConnectorError::WebhookResourceObjectNotFound |
errors::ConnectorError::WebhookResponseEncodingFailed |
errors::ConnectorError::InvalidDateFormat |
errors::ConnectorError::DateFormattingFailed |
errors::ConnectorError::InvalidWalletToken |
errors::ConnectorError::MissingConnectorRelatedTransactionID { .. } |
errors::ConnectorError::FileValidationFailed { .. } |
errors::ConnectorError::MissingConnectorRedirectionPayload { .. } |
errors::ConnectorError::FailedAtConnector { .. } |
errors::ConnectorError::MissingPaymentMethodType |
errors::ConnectorError::InSufficientBalanceInPaymentMethod |
errors::ConnectorError::RequestTimeoutReceived |
errors::ConnectorError::ProcessingStepFailed(None) => errors::ApiErrorResponse::InternalServerError
};
err.change_context(error)
})
Expand Down Expand Up @@ -235,8 +276,64 @@ impl<T> ConnectorErrorExt<T> for error_stack::Result<T, errors::ConnectorError>
errors::ConnectorError::MissingRequiredField { field_name } => {
errors::ApiErrorResponse::MissingRequiredField { field_name }
}
_ => {
logger::error!(%error,"Verify flow failed");
errors::ConnectorError::FailedToObtainIntegrationUrl => {
errors::ApiErrorResponse::InvalidConnectorConfiguration {
config: "connector_account_details".to_string(),
}
}
errors::ConnectorError::InvalidConnectorConfig { config: field_name } => {
errors::ApiErrorResponse::InvalidConnectorConfiguration {
config: field_name.to_string(),
}
}
errors::ConnectorError::RequestEncodingFailed
| errors::ConnectorError::RequestEncodingFailedWithReason(_)
| errors::ConnectorError::ParsingFailed
| errors::ConnectorError::ResponseDeserializationFailed
| errors::ConnectorError::UnexpectedResponseError(_)
| errors::ConnectorError::RoutingRulesParsingError
| errors::ConnectorError::FailedToObtainPreferredConnector
| errors::ConnectorError::InvalidConnectorName
| errors::ConnectorError::InvalidWallet
| errors::ConnectorError::ResponseHandlingFailed
| errors::ConnectorError::MissingRequiredFields { .. }
| errors::ConnectorError::FailedToObtainAuthType
| errors::ConnectorError::FailedToObtainCertificate
| errors::ConnectorError::NoConnectorMetaData
| errors::ConnectorError::FailedToObtainCertificateKey
| errors::ConnectorError::NotImplemented(_)
| errors::ConnectorError::NotSupported { .. }
| errors::ConnectorError::FlowNotSupported { .. }
| errors::ConnectorError::CaptureMethodNotSupported
| errors::ConnectorError::MissingConnectorMandateID
| errors::ConnectorError::MissingConnectorTransactionID
| errors::ConnectorError::MissingConnectorRefundID
| errors::ConnectorError::MissingApplePayTokenData
| errors::ConnectorError::WebhooksNotImplemented
| errors::ConnectorError::WebhookBodyDecodingFailed
| errors::ConnectorError::WebhookSignatureNotFound
| errors::ConnectorError::WebhookSourceVerificationFailed
| errors::ConnectorError::WebhookVerificationSecretNotFound
| errors::ConnectorError::WebhookVerificationSecretInvalid
| errors::ConnectorError::WebhookReferenceIdNotFound
| errors::ConnectorError::WebhookEventTypeNotFound
| errors::ConnectorError::WebhookResourceObjectNotFound
| errors::ConnectorError::WebhookResponseEncodingFailed
| errors::ConnectorError::InvalidDateFormat
| errors::ConnectorError::DateFormattingFailed
| errors::ConnectorError::InvalidDataFormat { .. }
| errors::ConnectorError::MismatchedPaymentData
| errors::ConnectorError::InvalidWalletToken
| errors::ConnectorError::MissingConnectorRelatedTransactionID { .. }
| errors::ConnectorError::FileValidationFailed { .. }
| errors::ConnectorError::MissingConnectorRedirectionPayload { .. }
| errors::ConnectorError::FailedAtConnector { .. }
| errors::ConnectorError::MissingPaymentMethodType
| errors::ConnectorError::InSufficientBalanceInPaymentMethod
| errors::ConnectorError::RequestTimeoutReceived
| errors::ConnectorError::CurrencyNotSupported { .. }
| errors::ConnectorError::ProcessingStepFailed(None) => {
logger::error!(%error,"Setup Mandate flow failed");
errors::ApiErrorResponse::PaymentAuthorizationFailed { data: None }
}
};
Expand Down

0 comments on commit 1dad745

Please sign in to comment.