hydrogen icon indicating copy to clipboard operation
hydrogen copied to clipboard

[BUG] Cannot dispatch event (cartCreate) for current cart state (creating)

Open magnuschase opened this issue 3 years ago • 0 comments

Describe the bug

Error: Cannot dispatch event (cartCreate) for current cart state (creating) popped up quite a bit after we moved our website to Oxygen from Vercel. We quickly realised, that it was popping out earlier, and on every hosting platform or localhost - if we haven't visited the page for a bit, and the token somehow became invalid (I don't know why though, because the expire date of the access token is longer than cookie expireAt), user couldn't add anything to cart, and errors popped up. It happened for a few of our users, and it took us quite a bit to debug, so I think that it would be nice to implement token checking, and if it's invalid, instead of throwing out errors that damage UX, just create a cart without a user, as we don't have enough control over the Cart components to create custom logic there.

To Reproduce

  1. Create a server component that uses useSession to get Customer Access Token, and then passes it to CartProvider
  2. Set a __session cookie with invalid token (use an old expired one, like %7B%22customerAccessToken%22%3A%22 1e6da9eca5aeea84f31cb08e44ebcf88%22%7D, but entirely fake one should also work)
  3. Try to add something to cart
  4. Item doesn't add5.
  5. Try to add something to cart again - unknown error pops up, and in console you see the error below

Expected behaviour

The storefront crashes, and the user is left confused

Something's wrong here... We found an error while loading this page. Please, refresh or go back to the home page

Error: Cannot dispatch event (cartCreate) for current cart state (creating) — CartProvider.client.js:455

Screenshots

Data returned from the query to the Storefront API on add to cart button click:

Zrzut ekranu 2022-07-13 o 10 46 12

Finał error:

Zrzut ekranu 2022-07-13 o 10 44 22

Additional context

  • Hydrogen v1.0.2
  • Node v16
  • Vercel, Oxygen, local env

Devices tested:

  • MacBook Pro M1 + macOS Monterey + Safari
  • iPhone 11 + iOS 15.5 + Safari

Fix proposal

I used the following code snippet to create a workaround for this bug:

import LocalCartProvider from './LocalCartProvider.client';

export default function ServerCartProvider({children}) {
  let { customerAccessToken } = useSession();

  // If we don't have a token, we pass the token as empty string 
  // then Hydrogen's add to cart function doesn't pass the token to the createCart mutation

  if (!customerAccessToken) return (
    <LocalCartProvider customerAccessToken={''}>
      {children}
    </LocalCartProvider>
  )

  // Fetch customer data

  const { data } = useShopQuery({
    query: QUERY,
    variables: {
      customerAccessToken,
    },
    cache: CacheNone(),
  });

  const customer = data && data.customer

  return (
    // Client-side component that renders our own cart provider + Hydrogen CartProvider component 

    <LocalCartProvider customerAccessToken={customer ? customerAccessToken : ''}>
      {children}
    </LocalCartProvider>
  );
}


const QUERY = gql`
  query CustomerDetails(
    $customerAccessToken: String!
  ) {
    customer(customerAccessToken: $customerAccessToken) {
      firstName
      lastName
      phone
      email
    }
  }
`;

magnuschase avatar Jul 13 '22 09:07 magnuschase