Skip to content

Commit

Permalink
Improve error message when you mix up @LiVe and non-live values.
Browse files Browse the repository at this point in the history
Reviewed By: alunyov

Differential Revision: D37732332

fbshipit-source-id: dc6056a3ba4054c08bc1f7d87a95b8f8b4833d06
  • Loading branch information
captbaritone authored and facebook-github-bot committed Jul 12, 2022
1 parent c4dbd26 commit 57f96a1
Show file tree
Hide file tree
Showing 6 changed files with 325 additions and 2 deletions.
60 changes: 60 additions & 0 deletions packages/react-relay/__tests__/LiveResolvers-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -1193,3 +1193,63 @@ describe.each([
expect(renderer.toJSON()).toBe('Loading...');
});
});

test('Errors when reading a @live resolver that does not return a LiveState object', () => {
const source = RelayRecordSource.create({
'client:root': {
__id: 'client:root',
__typename: '__Root',
},
});
const FooQuery = graphql`
query LiveResolversTest16Query {
live_resolver_with_bad_return_value
}
`;

const operation = createOperationDescriptor(FooQuery, {});
const store = new LiveResolverStore(source, {
gcReleaseBufferSize: 0,
});

const environment = new RelayModernEnvironment({
network: RelayNetwork.create(jest.fn()),
store,
});

expect(() => {
environment.lookup(operation.fragment);
}).toThrow(
'Expected the @live Relay Resolver backing the field "live_resolver_with_bad_return_value" to return a value that implements LiveState. Did you mean to remove the @live annotation on this resolver?',
);
});

test('Errors when reading a non-@live resolver that returns a LiveState object', () => {
const source = RelayRecordSource.create({
'client:root': {
__id: 'client:root',
__typename: '__Root',
},
});
const FooQuery = graphql`
query LiveResolversTest17Query {
non_live_resolver_with_live_return_value
}
`;

const operation = createOperationDescriptor(FooQuery, {});
const store = new LiveResolverStore(source, {
gcReleaseBufferSize: 0,
});

const environment = new RelayModernEnvironment({
network: RelayNetwork.create(jest.fn()),
store,
});

expect(() => {
environment.lookup(operation.fragment);
}).toThrow(
'Unexpected LiveState value retuned from the non-@live Relay Resolver backing the field "non_live_resolver_with_live_return_value". Did you intend to add @live to this resolver?.',
);
});

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @format
* @flow strict-local
* @emails oncall+relay
*/

'use strict';

/**
* @RelayResolver
* @fieldName live_resolver_with_bad_return_value
* @onType Query
* @live
*
* A @live resolver that does not return a LiveObject
*/
import type {LiveState} from '../../experimental-live-resolvers/LiveResolverStore';

function liveResolverWithBadReturnValue(): LiveState<string> {
// $FlowFixMe The purpose of this resolver is to test a bad return value.
return 'Oops!';
}

module.exports = liveResolverWithBadReturnValue;
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @format
* @flow strict-local
* @emails oncall+relay
*/

'use strict';

/**
* @RelayResolver
* @fieldName non_live_resolver_with_live_return_value
* @onType Query
*
* A non-@live resolver that returns a LiveObject
*/
import type {LiveState} from '../../experimental-live-resolvers/LiveResolverStore';

function nonLiveResolverWithLiveReturnValue(): LiveState<string> {
return {
read() {
return 'Oops!';
},
subscribe(cb) {
return () => {};
},
};
}

module.exports = nonLiveResolverWithLiveReturnValue;
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import type {
GetDataForResolverFragmentFn,
ResolverCache,
} from '../ResolverCache';
import type LiveResolverStore from './LiveResolverStore';
import type {LiveState} from './LiveResolverStore';

const recycleNodesInto = require('../../util/recycleNodesInto');
Expand All @@ -41,7 +42,6 @@ const {
RELAY_RESOLVER_VALUE_KEY,
getStorageKey,
} = require('../RelayStoreUtils');
const LiveResolverStore = require('./LiveResolverStore');
const {isSuspenseSentinel} = require('./LiveResolverSuspenseSentinel');
const invariant = require('invariant');
const warning = require('warning');
Expand Down Expand Up @@ -129,7 +129,9 @@ class LiveResolverCache implements ResolverCache {
if (__DEV__) {
invariant(
isLiveStateValue(evaluationResult.resolverResult),
'Expected a @live Relay Resolver to return a value that implements LiveState.',
'Expected the @live Relay Resolver backing the field "%s" to return a value ' +
'that implements LiveState. Did you mean to remove the @live annotation on this resolver?',
field.path,
);
}
const liveState: LiveState<mixed> =
Expand All @@ -138,6 +140,13 @@ class LiveResolverCache implements ResolverCache {
this._setLiveStateValue(linkedRecord, linkedID, liveState);
}
} else {
if (__DEV__) {
invariant(
!isLiveStateValue(evaluationResult.resolverResult),
'Unexpected LiveState value retuned from the non-@live Relay Resolver backing the field "%s". Did you intend to add @live to this resolver?.',
field.path,
);
}
RelayModernRecord.setValue(
linkedRecord,
RELAY_RESOLVER_VALUE_KEY,
Expand Down

0 comments on commit 57f96a1

Please sign in to comment.