Skip to content

Commit 10073c8

Browse files
XiNiHafacebook-github-bot
authored andcommitted
Fix observeFragment triggering unhandled rejections on network error (#4885)
Summary: This PR fixes an issue where `observeFragment` triggers unhandled rejections on network error, which happens because of the dangling promise created and dropped. Pull Request resolved: #4885 Reviewed By: tyao1 Differential Revision: D68505423 Pulled By: captbaritone fbshipit-source-id: 2df4afa40e140de7baea04e811f5c5b06f658a4f
1 parent 7201930 commit 10073c8

File tree

4 files changed

+206
-7
lines changed

4 files changed

+206
-7
lines changed

packages/relay-runtime/store/__tests__/__generated__/observeFragmentTestNetworkErrorFragment.graphql.js

Lines changed: 72 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/relay-runtime/store/__tests__/__generated__/observeFragmentTestNetworkErrorQuery.graphql.js

Lines changed: 98 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/relay-runtime/store/__tests__/observeFragment-test.js

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,35 @@ test('Missing required data', async () => {
145145
});
146146
});
147147

148+
test('Keep loading on network error', async () => {
149+
const query = graphql`
150+
query observeFragmentTestNetworkErrorQuery {
151+
...observeFragmentTestNetworkErrorFragment
152+
}
153+
`;
154+
155+
const fragment = graphql`
156+
fragment observeFragmentTestNetworkErrorFragment on Query {
157+
me {
158+
name
159+
}
160+
}
161+
`;
162+
163+
const environment = createMockEnvironment();
164+
const variables = {};
165+
const operation = createOperationDescriptor(query, variables);
166+
fetchQuery(environment, query, variables).subscribe({});
167+
const {data} = environment.lookup(operation.fragment);
168+
// $FlowFixMe Data is untyped
169+
const observable = observeFragment(environment, fragment, data);
170+
withObservableValues(observable, results => {
171+
expect(results).toEqual([{state: 'loading'}]);
172+
environment.mock.reject(operation, new Error('Network error'));
173+
expect(results).toEqual([{state: 'loading'}]);
174+
});
175+
});
176+
148177
test('Field error with @throwOnFieldError', async () => {
149178
const query = graphql`
150179
query observeFragmentTestThrowOnFieldErrorQuery {

packages/relay-runtime/store/observeFragmentExperimental.js

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ import type {
2020
} from 'relay-runtime';
2121

2222
const Observable = require('../network/RelayObservable');
23+
const {getObservableForActiveRequest} = require('../query/fetchQueryInternal');
2324
const {getFragment} = require('../query/GraphQLTag');
24-
const getPendingOperationsForFragment = require('../util/getPendingOperationsForFragment');
2525
const {
2626
handlePotentialSnapshotErrors,
2727
} = require('../util/handlePotentialSnapshotErrors');
@@ -241,12 +241,12 @@ function snapshotToFragmentState<TFragmentType: FragmentType, TData>(
241241
}
242242

243243
if (snapshot.isMissingData) {
244-
const pendingOperations = getPendingOperationsForFragment(
245-
environment,
246-
fragmentNode,
247-
owner,
248-
);
249-
if (pendingOperations != null) {
244+
if (
245+
getObservableForActiveRequest(environment, owner) != null ||
246+
environment
247+
.getOperationTracker()
248+
.getPendingOperationsAffectingOwner(owner) != null
249+
) {
250250
return {state: 'loading'};
251251
}
252252
}

0 commit comments

Comments
 (0)