diff --git a/.changeset/odd-melons-wash.md b/.changeset/odd-melons-wash.md new file mode 100644 index 0000000000..85961eb7f7 --- /dev/null +++ b/.changeset/odd-melons-wash.md @@ -0,0 +1,5 @@ +--- +'@shopify/hydrogen': patch +--- + +Make sure sub-requests that are 400 or 500 HTTP errors are not cached diff --git a/packages/hydrogen/src/hooks/useShopQuery/hooks.ts b/packages/hydrogen/src/hooks/useShopQuery/hooks.ts index 87e01bb2f1..1e026c93a4 100644 --- a/packages/hydrogen/src/hooks/useShopQuery/hooks.ts +++ b/packages/hydrogen/src/hooks/useShopQuery/hooks.ts @@ -18,12 +18,6 @@ export interface UseShopQueryResponse { errors: any; } -// Check if the response body has GraphQL errors -// https://spec.graphql.org/June2018/#sec-Response-Format -const shouldCacheResponse = (body: any) => { - return !body?.errors; -}; - /** * The `useShopQuery` hook allows you to make server-only GraphQL queries to the Storefront API. It must be a descendent of a `ShopifyProvider` component. */ @@ -77,6 +71,15 @@ export function useShopQuery({ const body = query ? graphqlRequestBody(query, variables) : ''; + let _response: Response; + + // Check if the response body has GraphQL errors + // https://spec.graphql.org/June2018/#sec-Response-Format + // and that the response is not an error + const shouldCacheResponse = (body: any) => { + return !body?.errors && _response?.ok; + }; + const {data, error} = useQuery( [storeDomain, storefrontApiVersion, body], async (request) => { @@ -89,7 +92,7 @@ export function useShopQuery({ storefrontId, privateStorefrontToken, }); - const response = await fetch(url, requestInit); + const response = (_response = await fetch(url, requestInit)); const text = await response.text(); try { diff --git a/packages/hydrogen/src/hooks/useShopQuery/tests/useShopQuery.test.tsx b/packages/hydrogen/src/hooks/useShopQuery/tests/useShopQuery.test.tsx index 5255b7e984..0f6f729540 100644 --- a/packages/hydrogen/src/hooks/useShopQuery/tests/useShopQuery.test.tsx +++ b/packages/hydrogen/src/hooks/useShopQuery/tests/useShopQuery.test.tsx @@ -102,4 +102,21 @@ describe('useShopQuery', () => { expect(await cache.keys()).toHaveLength(0); }); + + it('handles 500 errors', async () => { + mockedFetch.mockResolvedValue(new Response('{}', {status: 500})); + const component = await mountComponent(); + + expect(await cache.keys()).toHaveLength(0); + + await component.act(async () => { + await Promise.all(waitUntilPromises); + }); + + expect(component).toContainReactComponent('div', { + children: '{}', + }); + + expect(await cache.keys()).toHaveLength(0); + }); });