在承诺链中间捕获错误的最佳方法是什么

What is the best way catch an error in the middle of a promise chain?

本文关键字:最佳 方法 是什么 错误 承诺 中间      更新时间:2023-09-26

我有一个 Angular 结帐验证过程,它必须通过某些异步请求,这些请求在允许用户结帐之前发送表单信息。

我目前在初始$.ajax函数调用后.then()触发所有$.ajax调用。但是,我在承诺链中间捕获错误时遇到了问题。

下面的代码中,在.then($scope.sendShippingInformation)的第二个承诺调用中,这是我需要处理错误的地方。

你看,响应会给我一个键值对 response.extensionAttributes.errorMessage : 'error message here'; 如果表单上有错误。我需要能够向用户发出所述错误警报,并允许他们更正他们未正确输入的任何表单字段。允许他们修复它,然后再次处理信息。

我尝试添加success: someFunctionHereerror: someFunctionHere都无济于事。任何帮助将不胜感激。

// Initial $.ajax request
$scope.sendPaymentInformation = function() {
  console.log('Send Billing Info');
  var guestUrl = SOURCE_API + 'source/magento/V1/guest-carts/{cartId}/billing-address/';
  var loggedInUrl = SOURCE_API + 'source/magento/V1/carts/mine/billing-address/';
  var request = (KANE.isLoggedIn ? loggedInUrl : guestUrl);
  return $.ajax({
      method: 'POST',
      url: request,
      data: JSON.stringify({
        'address': {
          'region_code': 'TX',
          'country_id': KANE.territory,
          'street': ['1200 Lakeside Pkwy'],
          'postcode': $scope.creditCardZip,
          'city': 'Flower Mound',
          'firstname': 'Suraj',
          'lastname': 'Kolluri',
          'saveInAddressBook': 0,
          'telephone': $scope.phoneNumber,
          'email': $('#checkout-email').val(),
        }
      }),
      contentType: "application/json",
      dataType: "json"
    }).then($scope.sendShippingInformation)
    .then($scope.sendPaymentType)
    .then(function(response) {
      console.log(response);
    });
}
// Second Request where I need to handle the error 
$scope.sendShippingInformation = function() {
  console.log('Send Shipping Information');
  var guestUrl = SOURCE_API + 'source/magento/V1/guest-carts/{cartId}/shipping-information/';
  var loggedInUrl = SOURCE_API + 'source/magento/V1/carts/mine/shipping-information/';
  var request = (KANE.isLoggedIn ? loggedInUrl : guestUrl);
  return $.ajax({
    method: 'POST',
    url: request,
    data: JSON.stringify({
      'addressInformation': {
        'shippingAddress': {
          'region_code': $scope.state,
          'country_id': KANE.territory,
          'street': [$scope.streetAddress1],
          'postcode': $scope.zip,
          'city': $scope.city,
          'firstname': $scope.firstName,
          'lastname': $scope.lastName,
          'email': $scope.email,
          'telephone': $scope.phoneNumber,
        },
        'shippingMethodCode': templateShippingMethods[$scope.shippingMethod].method_code,
        'shippingCarrierCode': templateShippingMethods[$scope.shippingMethod].id
      }
    }),
    contentType: "application/json",
    dataType: "json"
  })
}
// Determine Payment Type
$scope.sendPaymentType = function() {
  if ($('#paypal').is(':checked')) {
    console.log("Checking Out With PayPal");
    var guestUrl = SOURCE_API + 'source/paypal/checkout/';
    var loggedInUrl = SOURCE_API + 'source/paypal/checkout/';
    var request = (KANE.isLoggedIn ? loggedInUrl : guestUrl);
    var products = [],
      total = 0;
    $('#my-cart .product').each(function(index, el) {
      total += parseFloat($(el).attr('data-total'));
      products.push({
        'name': $(el).attr('data-title'),
        'sku': $(el).attr('data-sku'),
        'price': $(el).attr('data-price'),
        'quantity': $(el).attr('data-qty')
      });
    });
    return $.ajax({
      method: 'POST',
      url: request,
      data: JSON.stringify({
        'items': products,
        'shipping_address': {
          'line1': $scope.streetAddress1,
          'line2': $scope.streetAddress2,
          'city': $scope.city,
          'country_code': KANE.territory,
          'postal_code': $scope.zip,
          'state': $scope.state,
          'phone': '9999999999',
          normalization_status: 'UNKNOWN',
          'status': 'CONFIRMED',
          'type': 'HOME',
          'recipient_name': $scope.firstName,
        },
        'total': KANE.cartObject.grandTotal,
        'currency': 'USD',
        'subtotal': KANE.cartObject.subtotal,
        'tax': '0.00',
        'shipping': parseFloat(templateShippingMethods[$scope.shippingMethod].price).toFixed(2).toString(),
        'shipping_discount': KANE.cartObject.discountAmount,
        'email': ($scope.email) ? $scope.email : '',
        'description': 'This is the payment transaction description.'
      }),
      contentType: "application/json",
      dataType: "json"
    }).then(function(response) {
      console.log(response.approvalUrl);
      window.location.replace(response.approvalUrl);
    })
  } else {
    console.log('Send Stripe Payment');
    var guestUrl = SOURCE_API + 'source/magento/V1/guest-carts/{cartId}/order/';
    var loggedInUrl = SOURCE_API + 'source/magento/V1/carts/mine/order/';
    if (KANE.isLoggedIn) {
      return $.ajax({
        method: 'PUT',
        url: loggedInUrl,
        data: JSON.stringify({
          "paymentMethod": {
            "method": "md_stripe_cards",
            "additionalData": {
              "md_stripe_card_id": userDataObject.savedPaymentMethods[$scope.paymentMethod].cardId,
              "md_stripe_customer_id": userDataObject.stripeCustId,
              "from_venue": "1"
            }
          },
        }),
        contentType: "application/json",
        dataType: "json"
      })
    } else {
      return $.ajax({
        method: 'POST',
        url: guestUrl,
        data: JSON.stringify({
          "paymentMethod": {
            "method": "md_stripe_cards",
            "additionalData": {
              "md_stripe_token": "tok_u5dg20Gra",
              "from_venue": "1"
            }
          }
        }),
        contentType: "application/json",
        dataType: "json"
      })
    }
  }
}

你可以尝试这样的事情:

(伪代码)

$scope.b_ok = false
$scope.give_up = false
p = a.then(
  while (!$scope.b_ok && !$scope.give_up) {
    p = b.then(c)
  }
)
p.catch(show_error)

在 B 中:

return ajax.then(set_b_ok_to_true).catch(tell_them_to_retry)

在tell_them_to_retry中,你会想要拒绝(原因),这样 c 就不会跟在 B 后面。