Network errors not caught by error boundary when using `useLazyLoadQuery`, `useFragment` and a `store-and/or-network` fetch policy in non-concurrent mode (and React Native)
- Dominant language
- Rust
- Stars
- 19k
- Forks
- 1.9k
- PR merge metrics
- No merged PRs in 30d
Description
> **Note:** I originally opened this issue as being React Native specific, however after testing in React DOM v17, this appears to be an issue common to all version of React running in non-concurrent mode (ie. `ReactDOM.render`) **and** all versions of React Native (which doesn't support concurrent mode prior to the new architecture).
This issue happens when using `useLazyLoadQuery` with a fetch policy of `store-and-network` or `store-or-network` **and** the data requiring network is specified in a `useFragment`. If a network error is raised, rather than being caught by the closest error boundary the component will instead render to completion _without_ it's required data, violating the type safety contracts. In production environments this results in JS level errors as the rendered components try and access data that isn't present.
I've created a [minimal reproduction in a CodeSandbox](https://codesandbox.io/s/react-18-relay-error-handling-rqbtno) where the network layer intentionally throws an Error to simulate the behaviour of a failing fetch/error response.
> React: 18.2.0
> Relay: 14.1.0
> Concurrent Mode: disabled
## Expected behaviour
The network error should halt the component render, and the network error should bubble up to be caught by the closest error boundary component.

## Observed behaviour
The network error is ignored and the component renders to completion. This results in JS `TypeError`s as the component will try and access data that is expected to be present. This breaks the type safety contract.

Curiously if you trigger another render in the component (e.g. by setting state) the error will then be correctly handled, it's only on the initial render that the error is ignored.
# Other test cases
```
❌ = bug is present
✅ = correct behaviour
```
## ❌ [React 18, Relay 14.1 - concurrent mode disabled](https://codesandbox.io/s/react-18-relay-error-handling-rqbtno)
> React: 18.2.0
> Relay: 14.1.0
> Concurrent Mode: disabled
## ❌ [React 17, Relay 14.1](https://codesandbox.io/s/react-17-relay-error-handling-bnd8d2)
> React: 17.0.2
> Relay: 14.1.0
React 17 doesn't support concurrent mode, so it exhibits the same issue.
## ❌ [React 18.2, Relay 11 - concurrent mode disabled](https://codesandbox.io/s/react-18-relay-error-handling-relay-11-4h5yr7)
> React: 18.2.0
> Relay: 11.0.2
> Concurrent Mode: disabled
This issue appears to be present in all versions of Relay hooks (`>=11.0.0`)
## ❌ [React 18, Relay nightly `0.0.0-main-f8ccd9af` - concurrent mode disabled](https://codesandbox.io/s/react-18-relay-error-handling-rqbtno)
> React: 18.2.0
> Relay: `0.0.0-main-f8ccd9af` f8ccd9af
> Concurrent Mode: disabled
Issue is present in the latest published nightly (as of December 23rd, 2022)
## ✅ [React 18 - Concurrent mode enabled](https://codesandbox.io/s/react-18-relay-error-handling-concurrent-mode-0gp3nw)
> React: 18.2.0
> Relay: 14.1.0
> Concurrent Mode: enabled
With concurrent mode enabled, the network error is successfully caught by the parent error boundary component.
## ✅ [React 18 - without fragment - concurrent mode disabled](https://codesandbox.io/s/react-18-relay-error-handling-no-fragment-e5zo7j)
> React: 18.2.0
> Relay: 14.1.0
> Concurrent Mode: disabled
If we omit the `useFragment` and instead define the data requirements entirely within the `useLazyLoadQuery`, the network error is handled correctly.
## ✅ [fetchPolicy: 'network-only' - concurrent mode disabled](https://codesandbox.io/s/react-18-relay-error-handling-network-only-8l10ys)
> React: 18.2.0
> Relay: 14.1.0
> Concurrent Mode: disabled
When using `fetchPolicy: 'network-only'` the error is handled correctly.
Contributor guide
Assessment
This issue has not been assessed yet.