Skip to content

Conversation

@alvarlagerlof
Copy link

@alvarlagerlof alvarlagerlof commented Aug 7, 2024

Debugging an issue where I see A query that was dehydrated as pending ended up rejecting. [${query?.queryHash}]: Error: server error; The error will be redacted in production builds logged, but my SSR render also returned a status code of 500.

Upon digging into the code, I think I found that hydrate() can cause an unhandled promise rejection from here when dehydrateQuery catches an error and returns a Promise.reject because a queryFn threw.

It seems like no tests are covering this, due to them ending before the rejection happens, but when I run the tests with the change in this PR, I get the following:

Test run ✔ nx run @tanstack/query-core:build [existing outputs match the cache, left as is] ✔ nx run @tanstack/query-persist-client-core:build [existing outputs match the cache, left as is] ✔ nx run @tanstack/react-query:build [existing outputs match the cache, left as is] ✔ nx run @tanstack/query-devtools:build [existing outputs match the cache, left as is] ✔ nx run @tanstack/react-query-persist-client:test:lib [existing outputs match the cache, left as is] ✔ nx run @tanstack/react-query-devtools:test:lib [existing outputs match the cache, left as is]

———————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
✖ nx run @tanstack/react-query:test:lib
> @tanstack/[email protected] test:lib /Users/alvar/Code/query/packages/react-query
> vitest --retry=3

  Testing types with tsc and vue-tsc is an experimental feature.
  Breaking changes might not follow SemVer, please pin Vitest's version when using it.
  
   RUN  v2.0.5 /Users/alvar/Code/query/packages/react-query
        Coverage enabled with istanbul
  
   ✓ |@tanstack/react-query| src/__tests__/queryOptions.test-d.tsx  (18 tests)
   ✓ |@tanstack/react-query| src/__tests__/infiniteQueryOptions.test-d.tsx  (10 tests)
   ✓ |@tanstack/react-query| src/__tests__/useQueries.test-d.tsx  (6 tests)
   ✓ |@tanstack/react-query| src/__tests__/useInfiniteQuery.test-d.tsx  (7 tests)
   ✓ |@tanstack/react-query| src/__tests__/useQuery.test-d.tsx  (9 tests)
   ✓ |@tanstack/react-query| src/__tests__/useSuspenseQueries.test-d.tsx  (6 tests)
   ✓ |@tanstack/react-query| src/__tests__/suspense.test-d.tsx  (9 tests)
   ✓ |@tanstack/react-query| src/__tests__/prefetch.test-d.tsx  (5 tests)
  stderr | src/__tests__/prefetch.test.tsx > usePrefetchQuery > should let errors fall through and not refetch failed queries
  Error: Oops! Server error!
      at /Users/alvar/Code/query/packages/react-query/src/__tests__/prefetch.test.tsx:137:13 {
    [stack]: 'Error: Oops! Server error!\n' +
      '    at /Users/alvar/Code/query/packages/react-query/src/__tests__/prefetch.test.tsx:137:13',
    [message]: 'Oops! Server error!'
  }
  
  The above error occurred in the <Suspended> component:
  
      at Suspended (/Users/alvar/Code/query/packages/react-query/src/__tests__/prefetch.test.tsx:39:64)
      at Suspense
      at ErrorBoundary (/Users/alvar/Code/query/node_modules/.pnpm/[email protected][email protected]/node_modules/react-error-boundary/dist/react-error-boundary.development.esm.js:14:5)
      at App (/Users/alvar/Code/query/packages/react-query/src/__tests__/prefetch.test.tsx:126:29)
      at QueryClientProvider (/Users/alvar/Code/query/packages/react-query/src/QueryClientProvider.tsx:400:3)
  
  React will try to recreate this component tree from scratch using the error boundary you provided, ErrorBoundary.
  
  stderr | src/__tests__/prefetch.test.tsx > usePrefetchQuery > should be able to recover from errors and try fetching again
  Error: Oops! Server error!
      at /Users/alvar/Code/query/packages/react-query/src/__tests__/prefetch.test.tsx:200:13 {
    [stack]: 'Error: Oops! Server error!\n' +
      '    at /Users/alvar/Code/query/packages/react-query/src/__tests__/prefetch.test.tsx:200:13',
    [message]: 'Oops! Server error!'
  }
  
  The above error occurred in the <Suspended> component:
  
      at Suspended (/Users/alvar/Code/query/packages/react-query/src/__tests__/prefetch.test.tsx:39:64)
      at Suspense
      at ErrorBoundary (/Users/alvar/Code/query/node_modules/.pnpm/[email protected][email protected]/node_modules/react-error-boundary/dist/react-error-boundary.development.esm.js:14:5)
      at App (/Users/alvar/Code/query/packages/react-query/src/__tests__/prefetch.test.tsx:204:47)
      at QueryClientProvider (/Users/alvar/Code/query/packages/react-query/src/QueryClientProvider.tsx:400:3)
  
  React will try to recreate this component tree from scratch using the error boundary you provided, ErrorBoundary.
  
   ✓ |@tanstack/react-query| src/__tests__/useQueries.test.tsx  (19 tests) 673ms
   ✓ |@tanstack/react-query| src/__tests__/useMutation.test.tsx  (23 tests) 869ms
  stderr | src/__tests__/prefetch.test.tsx > usePrefetchInfiniteQuery > should prefetch an infinite query if query state does not exist
  Warning: Each child in a list should have a unique "key" prop.
  
  Check the render method of `Suspended`. See https://react.dev/link/warning-keys for more information.
      at div
      at Suspended (/Users/alvar/Code/query/packages/react-query/src/__tests__/prefetch.test.tsx:337:72)
      at Suspense
      at App (/Users/alvar/Code/query/packages/react-query/src/__tests__/prefetch.test.tsx:366:29)
      at QueryClientProvider (/Users/alvar/Code/query/packages/react-query/src/QueryClientProvider.tsx:400:3)
  
   ✓ |@tanstack/react-query| src/__tests__/HydrationBoundary.test.tsx  (7 tests) 180ms
   ✓ |@tanstack/react-query| src/__tests__/ssr-hydration.test.tsx  (3 tests) 127ms
   ✓ |@tanstack/react-query| src/__tests__/QueryResetErrorBoundary.test.tsx  (13 tests) 1842ms
   ✓ |@tanstack/react-query| src/__tests__/prefetch.test.tsx  (9 tests) 1971ms
   ✓ |@tanstack/react-query| src/__tests__/useInfiniteQuery.test.tsx  (26 tests) 2448ms
   ✓ |@tanstack/react-query| src/__tests__/useSuspenseQueries.test.tsx  (6 tests) 37ms
   ✓ |@tanstack/react-query| src/__tests__/useIsFetching.test.tsx  (5 tests) 350ms
   ✓ |@tanstack/react-query| src/__tests__/fine-grained-persister.test.tsx  (3 tests) 46ms
   ✓ |@tanstack/react-query| src/__tests__/useMutationState.test.tsx  (7 tests) 732ms
   ✓ |@tanstack/react-query| src/__tests__/ssr.test.tsx  (5 tests) 15ms
   ✓ |@tanstack/react-query| src/__tests__/QueryClientProvider.test.tsx  (4 tests) 62ms
   ✓ |@tanstack/react-query| src/__tests__/suspense.test.tsx  (22 tests) 10490ms
   ❯ |@tanstack/react-query| src/__tests__/useQuery.test.tsx  (139 tests | 1 failed) 10864ms
     × useQuery > should retry failed initialPromise on the client
       → Unable to find an element with the text: failure: redacted. This could be because the text is broken up by multiple elements. In this case, you can provide a function for your text matcher to make your matcher more flexible.
  
  Ignored nodes: comments, script, style
  <body>
    <div>
      <div>
        <div>
          failure: 
        </div>
        <div>
          data: 
          client
        </div>
      </div>
    </div>
  </body>
  
  Ignored nodes: comments, script, style
  <html>
    <head />
    <body>
      <div>
        <div>
          <div>
            failure: 
          </div>
          <div>
            data: 
            client
          </div>
        </div>
      </div>
    </body>
  </html>
       → Unable to find an element with the text: failure: redacted. This could be because the text is broken up by multiple elements. In this case, you can provide a function for your text matcher to make your matcher more flexible.
  
  Ignored nodes: comments, script, style
  <body>
    <div>
      <div>
        <div>
          failure: 
        </div>
        <div>
          data: 
          client
        </div>
      </div>
    </div>
  </body>
  
  Ignored nodes: comments, script, style
  <html>
    <head />
    <body>
      <div>
        <div>
          <div>
            failure: 
          </div>
          <div>
            data: 
            client
          </div>
        </div>
      </div>
    </body>
  </html>
       → Unable to find an element with the text: failure: redacted. This could be because the text is broken up by multiple elements. In this case, you can provide a function for your text matcher to make your matcher more flexible.
  
  Ignored nodes: comments, script, style
  <body>
    <div>
      <div>
        <div>
          failure: 
        </div>
        <div>
          data: 
          client
        </div>
      </div>
    </div>
  </body>
  
  Ignored nodes: comments, script, style
  <html>
    <head />
    <body>
      <div>
        <div>
          <div>
            failure: 
          </div>
          <div>
            data: 
            client
          </div>
        </div>
      </div>
    </body>
  </html>
       → Unable to find an element with the text: failure: redacted. This could be because the text is broken up by multiple elements. In this case, you can provide a function for your text matcher to make your matcher more flexible.
  
  Ignored nodes: comments, script, style
  <body>
    <div>
      <div>
        <div>
          failure: 
        </div>
        <div>
          data: 
          client
        </div>
      </div>
    </div>
  </body>
  
  Ignored nodes: comments, script, style
  <html>
    <head />
    <body>
      <div>
        <div>
          <div>
            failure: 
          </div>
          <div>
            data: 
            client
          </div>
        </div>
      </div>
    </body>
  </html>
  
  ⎯⎯⎯⎯⎯⎯⎯ Failed Tests 1 ⎯⎯⎯⎯⎯⎯⎯
  
   FAIL  |@tanstack/react-query| src/__tests__/useQuery.test.tsx > useQuery > should retry failed initialPromise on the client
   FAIL  |@tanstack/react-query| src/__tests__/useQuery.test.tsx > useQuery > should retry failed initialPromise on the client
   FAIL  |@tanstack/react-query| src/__tests__/useQuery.test.tsx > useQuery > should retry failed initialPromise on the client
   FAIL  |@tanstack/react-query| src/__tests__/useQuery.test.tsx > useQuery > should retry failed initialPromise on the client
  TestingLibraryElementError: Unable to find an element with the text: failure: redacted. This could be because the text is broken up by multiple elements. In this case, you can provide a function for your text matcher to make your matcher more flexible.
  
  Ignored nodes: comments, script, style
  <body>
    <div>
      <div>
        <div>
          failure: 
        </div>
        <div>
          data: 
          client
        </div>
      </div>
    </div>
  </body>
  
  Ignored nodes: comments, script, style
  <html>
    <head />
    <body>
      <div>
        <div>
          <div>
            failure: 
          </div>
          <div>
            data: 
            client
          </div>
        </div>
      </div>
    </body>
  </html>
   ❯ Proxy.waitForWrapper ../../node_modules/.pnpm/@[email protected]/node_modules/@testing-library/dom/dist/wait-for.js:163:27
   ❯ src/__tests__/useQuery.test.tsx:6587:11
      6585| 
      6586|     const rendered = renderWithClient(clientQueryClient, <Page />)
      6587|     await waitFor(() => rendered.getByText('failure: redacted'))
         |           ^
      6588|     await waitFor(() => rendered.getByText('data: client'))
      6589|     expect(count).toBe(1)
  
  ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[1/4]⎯
  
  ⎯⎯⎯⎯⎯⎯ Unhandled Errors ⎯⎯⎯⎯⎯⎯
  
  Vitest caught 4 unhandled errors during the test run.
  This might cause false positive tests. Resolve unhandled errors to make sure your tests are not affected.
  
  ⎯⎯⎯⎯ Unhandled Rejection ⎯⎯⎯⎯⎯
  Error: redacted
   ❯ ../query-core/src/hydration.ts:90:31
  
  This error originated in "src/__tests__/useQuery.test.tsx" test file. It doesn't mean the error was thrown inside the file itself, but while it was running.
  The latest test that might've caused the error is "should retry failed initialPromise on the client". It might mean one of the following:
  - The error was thrown, while Vitest was running this test.
  - If the error occurred after the test had been completed, this was the last documented test before it was thrown.
  
  ⎯⎯⎯⎯ Unhandled Rejection ⎯⎯⎯⎯⎯
  Error: redacted
   ❯ ../query-core/src/hydration.ts:90:31
  
  This error originated in "src/__tests__/useQuery.test.tsx" test file. It doesn't mean the error was thrown inside the file itself, but while it was running.
  The latest test that might've caused the error is "should retry failed initialPromise on the client". It might mean one of the following:
  - The error was thrown, while Vitest was running this test.
  - If the error occurred after the test had been completed, this was the last documented test before it was thrown.
  
  ⎯⎯⎯⎯ Unhandled Rejection ⎯⎯⎯⎯⎯
  Error: redacted
   ❯ ../query-core/src/hydration.ts:90:31
  
  This error originated in "src/__tests__/useQuery.test.tsx" test file. It doesn't mean the error was thrown inside the file itself, but while it was running.
  The latest test that might've caused the error is "should retry failed initialPromise on the client". It might mean one of the following:
  - The error was thrown, while Vitest was running this test.
  - If the error occurred after the test had been completed, this was the last documented test before it was thrown.
  
  ⎯⎯⎯⎯ Unhandled Rejection ⎯⎯⎯⎯⎯
  Error: redacted
   ❯ ../query-core/src/hydration.ts:90:31
  
  This error originated in "src/__tests__/useQuery.test.tsx" test file. It doesn't mean the error was thrown inside the file itself, but while it was running.
  The latest test that might've caused the error is "should retry failed initialPromise on the client". It might mean one of the following:
  - The error was thrown, while Vitest was running this test.
  - If the error occurred after the test had been completed, this was the last documented test before it was thrown.
  ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯
  
   Test Files  1 failed | 22 passed (23)
        Tests  1 failed | 360 passed (361)
  Type Errors  no errors
       Errors  4 errors
     Start at  16:52:31
     Duration  15.39s (transform 1.15s, setup 9.32s, collect 4.87s, tests 30.71s, environment 18.06s, prepare 1.41s, typecheck 2.72s)
  
   ELIFECYCLE  Command failed with exit code 1.

———————————————————————————————————————————————————————————————————————————————————————————————————————————————————————

NX Ran target test:lib for 3 projects and 4 tasks they depend on (19s)

✔ 6/7 succeeded [6 read from cache]

✖ 1/7 targets failed, including the following:

  - nx run @tanstack/react-query:test:lib

View structured, searchable error logs at https://nx.app/runs/yruFhd2Ecu

 ELIFECYCLE  Command failed with exit code 1.

@alvarlagerlof alvarlagerlof changed the title [WIP] repro hydrate() throws after test completion [WIP] repro hydrate() causes unhandled promise rejection with a throwing prefetchQuery Aug 7, 2024
@TkDodo
Copy link
Collaborator

TkDodo commented Sep 21, 2024

@alvarlagerlof is this happening because of the .then chain?

const initialPromise = Promise.resolve(promise).then(deserializeData)

Ideally, what we wanted to achieve is if the promise from the server fails, it would get retried on the client (since we pass it to the retryer). I'm wondering if adding a .catch(noop) here would stop those retries from happening ...

@alvarlagerlof
Copy link
Author

alvarlagerlof commented Sep 21, 2024

@alvarlagerlof is this happening because of the .then chain?

Yes the lack of .catch causes an unhandled promise rejection.

Ideally, what we wanted to achieve is if the promise from the server fails, it would get retried on the client (since we pass it to the retryer). I'm wondering if adding a .catch(noop) here would stop those retries from happening ...

I realised the same about the retries. I tried adding .catch(() => {}) that does ofc fix the unhandled promise, but as you suspected it breaks retries.

Test log

```

  ⎯⎯⎯⎯⎯⎯⎯ Failed Tests 1 ⎯⎯⎯⎯⎯⎯⎯
  
   FAIL  |@tanstack/react-query| src/__tests__/useQuery.test.tsx > useQuery > should retry failed initialPromise on the client
  TestingLibraryElementError: Unable to find an element with the text: failure: redacted. This could be because the text is broken up by multiple elements. In this case, you can provide a function for your text matcher to make your matcher more flexible.
  
  Ignored nodes: comments, script, style
  <body>
    <div>
      <div>
        <div>
          failure: 
          ["query_136"] data is undefined
        </div>
        <div>
          data: 
        </div>
      </div>
    </div>
  </body>
  
  Ignored nodes: comments, script, style
  <html>
    <head />
    <body>
      <div>
        <div>
          <div>
            failure: 
            ["query_136"] data is undefined
          </div>
          <div>
            data: 
          </div>
        </div>
      </div>
    </body>
  </html>
   ❯ Proxy.waitForWrapper ../../node_modules/.pnpm/@[email protected]/node_modules/@testing-library/dom/dist/wait-for.js:163:27
   ❯ src/__tests__/useQuery.test.tsx:6586:11
      6584| 
      6585|     const rendered = renderWithClient(clientQueryClient, <Page />)
      6586|     await waitFor(() => rendered.getByText('failure: redacted'))
         |           ^
      6587|     await waitFor(() => rendered.getByText('data: client'))
      6588|     expect(count).toBe(1)
  
  ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[1/4]⎯
  
   FAIL  |@tanstack/react-query| src/__tests__/useQuery.test.tsx > useQuery > should retry failed initialPromise on the client
  TestingLibraryElementError: Unable to find an element with the text: failure: redacted. This could be because the text is broken up by multiple elements. In this case, you can provide a function for your text matcher to make your matcher more flexible.
  
  Ignored nodes: comments, script, style
  <body>
    <div>
      <div>
        <div>
          failure: 
          ["query_137"] data is undefined
        </div>
        <div>
          data: 
        </div>
      </div>
    </div>
  </body>
  
  Ignored nodes: comments, script, style
  <html>
    <head />
    <body>
      <div>
        <div>
          <div>
            failure: 
            ["query_137"] data is undefined
          </div>
          <div>
            data: 
          </div>
        </div>
      </div>
    </body>
  </html>
   ❯ Proxy.waitForWrapper ../../node_modules/.pnpm/@[email protected]/node_modules/@testing-library/dom/dist/wait-for.js:163:27
   ❯ src/__tests__/useQuery.test.tsx:6586:11
      6584| 
      6585|     const rendered = renderWithClient(clientQueryClient, <Page />)
      6586|     await waitFor(() => rendered.getByText('failure: redacted'))
         |           ^
      6587|     await waitFor(() => rendered.getByText('data: client'))
      6588|     expect(count).toBe(1)
  
  ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[2/4]⎯
  
   FAIL  |@tanstack/react-query| src/__tests__/useQuery.test.tsx > useQuery > should retry failed initialPromise on the client
  TestingLibraryElementError: Unable to find an element with the text: failure: redacted. This could be because the text is broken up by multiple elements. In this case, you can provide a function for your text matcher to make your matcher more flexible.
  
  Ignored nodes: comments, script, style
  <body>
    <div>
      <div>
        <div>
          failure: 
          ["query_138"] data is undefined
        </div>
        <div>
          data: 
        </div>
      </div>
    </div>
  </body>
  
  Ignored nodes: comments, script, style
  <html>
    <head />
    <body>
      <div>
        <div>
          <div>
            failure: 
            ["query_138"] data is undefined
          </div>
          <div>
            data: 
          </div>
        </div>
      </div>
    </body>
  </html>
   ❯ Proxy.waitForWrapper ../../node_modules/.pnpm/@[email protected]/node_modules/@testing-library/dom/dist/wait-for.js:163:27
   ❯ src/__tests__/useQuery.test.tsx:6586:11
      6584| 
      6585|     const rendered = renderWithClient(clientQueryClient, <Page />)
      6586|     await waitFor(() => rendered.getByText('failure: redacted'))
         |           ^
      6587|     await waitFor(() => rendered.getByText('data: client'))
      6588|     expect(count).toBe(1)
  
  ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[3/4]⎯
  
   FAIL  |@tanstack/react-query| src/__tests__/useQuery.test.tsx > useQuery > should retry failed initialPromise on the client
  TestingLibraryElementError: Unable to find an element with the text: failure: redacted. This could be because the text is broken up by multiple elements. In this case, you can provide a function for your text matcher to make your matcher more flexible.
  
  Ignored nodes: comments, script, style
  <body>
    <div>
      <div>
        <div>
          failure: 
          ["query_139"] data is undefined
        </div>
        <div>
          data: 
        </div>
      </div>
    </div>
  </body>
  
  Ignored nodes: comments, script, style
  <html>
    <head />
    <body>
      <div>
        <div>
          <div>
            failure: 
            ["query_139"] data is undefined
          </div>
          <div>
            data: 
          </div>
        </div>
      </div>
    </body>
  </html>
   ❯ Proxy.waitForWrapper ../../node_modules/.pnpm/@[email protected]/node_modules/@testing-library/dom/dist/wait-for.js:163:27
   ❯ src/__tests__/useQuery.test.tsx:6586:11
      6584| 
      6585|     const rendered = renderWithClient(clientQueryClient, <Page />)
      6586|     await waitFor(() => rendered.getByText('failure: redacted'))
         |           ^
      6587|     await waitFor(() => rendered.getByText('data: client'))
      6588|     expect(count).toBe(1)
  
  ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[4/4]⎯
  
   Test Files  1 failed | 22 passed (23)
        Tests  1 failed | 360 passed (361)
  Type Errors  no errors
     Start at  12:22:17
     Duration  19.78s (transform 6.78s, setup 11.99s, collect 22.31s, tests 34.73s, environment 22.41s, prepare 6.71s, typecheck 18.40s)
  
   ELIFECYCLE  Command failed with exit code 1.
</p>
</details> 

@TkDodo
Copy link
Collaborator

TkDodo commented Sep 21, 2024

Not sure why it's "unhandled" then. The retryer does handle it 😅 - on the client

@alvarlagerlof
Copy link
Author

Not sure why it's "unhandled" then. The retryer does handle it 😅 - on the client

I just tried this:

      // Note: `Promise.resolve` required cause
      // RSC transformed promises are not thenable
      const initialPromise = Promise.resolve(promise).then(deserializeData)

      // this doesn't actually fetch - it just creates a retryer
      // which will re-use the passed `initialPromise`
      void query.fetch(undefined, { initialPromise }).catch(() => {
        /* noop */
      }

It also resolved the unhandled promise rejection. So maybe something in the fetch is actually where the issue lies.

But the added sleep seems to cause a test fail regardless:

Test log

       FAIL  |@tanstack/react-query| src/__tests__/useQuery.test.tsx > useQuery > should retry failed initialPromise on the client
      TestingLibraryElementError: Unable to find an element with the text: failure: redacted. This could be because the text is broken up by multiple elements. In this case, you can provide a function for your text matcher to make your matcher more flexible.
      
      Ignored nodes: comments, script, style
      <body>
        <div>
          <div>
            <div>
              failure: 
            </div>
            <div>
              data: 
              client
            </div>
          </div>
        </div>
      </body>
      
      Ignored nodes: comments, script, style
      <html>
        <head />
        <body>
          <div>
            <div>
              <div>
                failure: 
              </div>
              <div>
                data: 
                client
              </div>
            </div>
          </div>
        </body>
      </html>
       ❯ Proxy.waitForWrapper ../../node_modules/.pnpm/@[email protected]/node_modules/@testing-library/dom/dist/wait-for.js:163:27
       ❯ src/__tests__/useQuery.test.tsx:6587:11
          6585| 
          6586|     const rendered = renderWithClient(clientQueryClient, <Page />)
          6587|     await waitFor(() => rendered.getByText('failure: redacted'))
             |           ^
          6588|     await waitFor(() => rendered.getByText('data: client'))
          6589|     expect(count).toBe(1)
      
      ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[1/4]⎯
      
       Test Files  1 failed | 22 passed (23)
            Tests  1 failed | 360 passed (361)
      Type Errors  no errors
         Start at  14:23:31
         Duration  16.57s (transform 4.25s, setup 6.11s, collect 12.24s, tests 36.34s, environment 12.65s, prepare 3.76s, typecheck 10.56s)
      
       ELIFECYCLE  Command failed with exit code 1.

Copy link
Collaborator

@Ephem Ephem left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@alvarlagerlof Thanks again for reporting this back when! I tried reproducing the unhandled error now but can't, so as your last comment suggested, this might not have been hydration-specific after all and seems to have been fixed by other work meanwhile (because I'm sure I've also seen unhandled errors around this in the past). The test error turns out to be unrelated as described in another comment.

I'll go ahead and close this, but do feel free to verify and reopen if you are still seeing unhandled promise rejection errors!

defaultOptions: { hydrate: { queries: { retry: 1, retryDelay: 10 } } },
})
hydrate(clientQueryClient, dehydrated)
await sleep(400)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is causing the fetch to fail before rendering, which means the client can immediately retry on rendering, putting the query in a fetching state, so the redacted will never get printed to the DOM.

If you instead inspect the queryCache directly, it's there.
If you instead put the await between the two waitFor below, the test succeeds again.

So while this might have surfaced an unhandled error in the past, the actual test fail seems to be unrelated.

@Ephem Ephem closed this Jan 10, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants