Repository: juspay/hyperswitch
File: crates/router/src/core/payments/retry.rs (Rust)

Code before:
                    let clear_pan_possible = initial_gsm
                        .and_then(|data| data.feature_data.get_retry_feature_data())
                        .map(|data| data.is_clear_pan_possible())
                        .unwrap_or(false);

                    let should_retry_with_pan = is_network_token
                        && clear_pan_possible
                        && business_profile.is_clear_pan_retries_enabled;

                    let (connector, routing_decision) = if should_retry_with_pan {
                        // If should_retry_with_pan is true, it indicates that we are retrying with PAN using the same connector.
                        (original_connector_data.clone(), None)
                    } else {
                        let connector_routing_data =
                            super::get_connector_data(&mut connector_routing_data)?;
                        let routing_decision = connector_routing_data.network.map(|card_network| {
                            routing_helpers::RoutingDecisionData::get_debit_routing_decision_data(
                                card_network,
                                None,
                            )
                        });

                        (connector_routing_data.connector_data, routing_decision)
                    };

                    if payment_data
                        .get_payment_intent()
                        .off_session
                        .unwrap_or(false)
                    {
                        let current_connector_routing_data =
                            super::get_connector_data(&mut connector_routing_data)?;
                        let payment_method_info = payment_data
                            .get_payment_method_info()
                            .get_required_value("payment_method_info")?
                            .clone();
                        let mandate_reference_id = payments::get_mandate_reference_id(
                            current_connector_routing_data.action_type.clone(),
                            current_connector_routing_data,
                            payment_data,
                            &payment_method_info,
                        )?;
                        payment_data.set_mandate_id(api_models::payments::MandateIds {
                            mandate_id: None,
                            mandate_reference_id, //mandate_ref_id
                        });
                    }

                    router_data = do_retry(
                        &state.clone(),
                        req_state.clone(),

Review comment (bug):
Correct me if I am wrong
If the code is reaching this place that means the payment has failed and it can be retried, which our auto retry. In such cases aren't we suppose to chose a different connector each time ?

For example 
Retryable Connectors = [Adyen(Connector Mandate), Adyen(CardWithNetworkTransactionId), Cybersource(NetworkTokenWithNetworkTransactionId), Cybersource(CardWithNetworkTransactionId), Stripe(CardWithNetworkTransactionId)]

If the first payment happened -> Adyen(Connector Mandate) and failed
And the GSM record says retry then it would because of connector error, right ?
If yes, in such cases we can not use `get_connector_data` as it just gives the next element from the list. In this case it is `Adyen(CardWithNetworkTransactionId)`. But as it is connector error we should retry with Cybersource(NetworkTokenWithNetworkTransactionId).

Code after:
                    let clear_pan_possible = initial_gsm
                        .and_then(|data| data.feature_data.get_retry_feature_data())
                        .map(|data| data.is_clear_pan_possible())
                        .unwrap_or(false);

                    let should_retry_with_pan = is_network_token
                        && clear_pan_possible
                        && business_profile.is_clear_pan_retries_enabled;

                    // Currently we are taking off_session as a source of truth to identify MIT payments.
                    let is_mit_payment = payment_data
                        .get_payment_intent()
                        .off_session
                        .unwrap_or(false);

                    let (connector, routing_decision) = if is_mit_payment {
                        let connector_routing_data =
                            super::get_connector_data(&mut connector_routing_data)?;
                        let payment_method_info = payment_data
                            .get_payment_method_info()
                            .get_required_value("payment_method_info")?
                            .clone();
                        let mandate_reference_id = payments::get_mandate_reference_id(
                            connector_routing_data.action_type.clone(),
                            connector_routing_data.clone(),
                            payment_data,
                            &payment_method_info,
                        )?;
                        payment_data.set_mandate_id(api_models::payments::MandateIds {
                            mandate_id: None,
                            mandate_reference_id, //mandate_ref_id
                        });
                        (connector_routing_data.connector_data, None)
                    } else if should_retry_with_pan {
                        // If should_retry_with_pan is true, it indicates that we are retrying with PAN using the same connector.
                        (original_connector_data.clone(), None)
                    } else {
                        let connector_routing_data =
                            super::get_connector_data(&mut connector_routing_data)?;
                        let routing_decision = connector_routing_data.network.map(|card_network| {
                            routing_helpers::RoutingDecisionData::get_debit_routing_decision_data(
                                card_network,
                                None,
                            )
                        });

                        (connector_routing_data.connector_data, routing_decision)
                    };

                    router_data = do_retry(
                        &state.clone(),