Ver código fonte

fix(core): Fix concurrent order address update edge case

Michael Bromley 2 anos atrás
pai
commit
f4ca9b23b7

+ 12 - 12
packages/core/e2e/shop-order.e2e-spec.ts

@@ -2265,18 +2265,18 @@ describe('Shop orders', () => {
             };
 
             await Promise.all([
-                shopClient.query<SetBillingAddress.Mutation, SetBillingAddress.Variables>(
-                    SET_BILLING_ADDRESS,
-                    {
-                        input: billingAddress,
-                    },
-                ),
-                shopClient.query<SetShippingAddress.Mutation, SetShippingAddress.Variables>(
-                    SET_SHIPPING_ADDRESS,
-                    {
-                        input: shippingAddress,
-                    },
-                ),
+                shopClient.query<
+                    CodegenShop.SetBillingAddressMutation,
+                    CodegenShop.SetBillingAddressMutationVariables
+                >(SET_BILLING_ADDRESS, {
+                    input: billingAddress,
+                }),
+                shopClient.query<
+                    CodegenShop.SetShippingAddressMutation,
+                    CodegenShop.SetShippingAddressMutationVariables
+                >(SET_SHIPPING_ADDRESS, {
+                    input: shippingAddress,
+                }),
             ]);
 
             const { activeOrder } = await shopClient.query(gql`

+ 7 - 1
packages/core/src/service/services/order.service.ts

@@ -36,6 +36,7 @@ import {
     TransitionPaymentToStateResult,
     UpdateOrderNoteInput,
 } from '@vendure/common/lib/generated-types';
+import { omit } from '@vendure/common/lib/omit';
 import { ID, PaginatedList } from '@vendure/common/lib/shared-types';
 import { summate } from '@vendure/common/lib/shared-utils';
 import { In, IsNull } from 'typeorm';
@@ -1694,7 +1695,12 @@ export class OrderService {
             promotions,
             updatedOrderLines ?? [],
         );
-        await this.connection.getRepository(ctx, Order).save(updatedOrder, { reload: false });
+        await this.connection
+            .getRepository(ctx, Order)
+            // Explicitly omit the shippingAddress and billingAddress properties to avoid
+            // a race condition where changing one or the other in parallel can
+            // overwrite the other's changes.
+            .save(omit(updatedOrder, ['shippingAddress', 'billingAddress']), { reload: false });
         await this.connection.getRepository(ctx, OrderLine).save(updatedOrder.lines, { reload: false });
         await this.connection.getRepository(ctx, ShippingLine).save(order.shippingLines, { reload: false });
         await this.promotionService.runPromotionSideEffects(ctx, order, activePromotionsPre);