facebook / relay

Relay is a JavaScript framework for building data-driven React applications.
https://relay.dev
MIT License
18.41k stars 1.83k forks source link

Hooks - Suspended `useFragment` component not throwing underlying fetchQuery error #3418

Open azz opened 3 years ago

azz commented 3 years ago

Say I have a container component which just spreads fragments (i.e., does not suspend):

function Container() {
  const data = useLazyLoadQuery(graphql`
    query ContainerQuery {
      ...Component_data
    }
  `);
  return <Component data={data} />;
}

And then a fragment component:

function Component(props) {
  const {viewer} = useFragment(
    graphql`
      fragment Component_data on Query {
        viewer { id }
      }
    `,
    props.data
  );
  return viewer.id;
}

When Component is rendered, it suspends correctly, however if the fetchQuery promise for ContainerQuery rejects with an error, instead of that error being propagated from the useFragment callsite, the useFragment returns an empty dataset (e.g. viewer is undefined above).

There are two issues here:

sibelius commented 3 years ago

Can you share your network layer code?

azz commented 3 years ago

Here is a cut-down version of fetchQuery:

function fetchQuery(operation, variables) {
  return fetch('/graph', {
    method: 'POST',
    headers: {},
    body: JSON.stringify({ query: operation.text, variables }),
  }).then(async response => {
    if (!response.ok) {
      throw new Error('oh no!');
    }
    const json = await response.json();
    return json;
  });
}
akiym commented 3 years ago

I hit the same problem. My reproduction code is here: https://codesandbox.io/s/ecstatic-sanne-dqyeo?file=/src/TodoApp.tsx

audiolion commented 3 years ago

Also ran into this error, I expected the error boundary to be hit but the suspended app resolves and tries to render instead.

stale[bot] commented 2 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

audiolion commented 2 years ago

bad stalebot

abilash-arista commented 1 year ago

I'm hitting the same error as well. An error thrown from inside the fetchQuery function, isn't getting caught by the error boundary. Instead it is trying to render the Fragment and throwing an error "Uncaught TypeError: Cannot read properties of undefined (reading 'name')".

levibuzolic commented 1 year ago

@abilash-arista using UNSTABLE_renderPolicy: 'full' or React concurrent mode should work around this issue, more details in #4146

abilash-arista commented 1 year ago

@abilash-arista using UNSTABLE_renderPolicy: 'full' or React concurrent mode should work around this issue, more details in #4146

@levibuzolic Awesome, thanks for pointing me to the correct issue! Using React concurrent mode fixed it for me.