Skip to content

Commit

Permalink
Warn if *within a single response* the same id has conflicting fields
Browse files Browse the repository at this point in the history
Reviewed By: tyao1

Differential Revision: D21909007

fbshipit-source-id: dec15d397f8e31efc25974cdd2e7b0a45dfd68e5
  • Loading branch information
David Massart authored and facebook-github-bot committed Jun 12, 2020
1 parent 72e32ec commit 87520d3
Show file tree
Hide file tree
Showing 2 changed files with 436 additions and 0 deletions.
78 changes: 78 additions & 0 deletions packages/relay-runtime/store/RelayResponseNormalizer.js
Original file line number Diff line number Diff line change
Expand Up @@ -442,11 +442,23 @@ class RelayResponseNormalizer {
return;
}
}
if (selection.kind === SCALAR_FIELD && __DEV__) {
this._validateConflictingFieldsWithIdenticalId(
record,
storageKey,
fieldValue,
);
}
RelayModernRecord.setValue(record, storageKey, null);
return;
}

if (selection.kind === SCALAR_FIELD) {
this._validateConflictingFieldsWithIdenticalId(
record,
storageKey,
fieldValue,
);
RelayModernRecord.setValue(record, storageKey, fieldValue);
} else if (selection.kind === LINKED_FIELD) {
this._path.push(responseKey);
Expand Down Expand Up @@ -496,6 +508,14 @@ class RelayResponseNormalizer {
'RelayResponseNormalizer: Expected id on field `%s` to be a string.',
storageKey,
);
if (__DEV__) {
this._validateConflictingLinkedFieldsWithIdenticalId(
record,
RelayModernRecord.getLinkedRecordID(record, storageKey),
nextID,
storageKey,
);
}
RelayModernRecord.setLinkedRecordID(record, storageKey, nextID);
let nextRecord = this._recordSource.get(nextID);
if (!nextRecord) {
Expand Down Expand Up @@ -577,6 +597,14 @@ class RelayResponseNormalizer {
} else if (__DEV__) {
this._validateRecordType(nextRecord, field, item);
}
if (prevIDs && __DEV__) {
this._validateConflictingLinkedFieldsWithIdenticalId(
record,
prevIDs[nextIndex],
nextID,
storageKey,
);
}
/* $FlowFixMe(>=0.98.0 site=www,mobile,react_native_fb,oss) This comment
* suppresses an error found when Flow v0.98 was deployed. To see the
* error delete this comment and run Flow. */
Expand Down Expand Up @@ -609,6 +637,56 @@ class RelayResponseNormalizer {
typeName,
);
}

/**
* Warns if a single response contains conflicting fields with the same id
*/
_validateConflictingFieldsWithIdenticalId(
record: Record,
storageKey: string,
fieldValue: mixed,
): void {
if (__DEV__) {
const dataID = RelayModernRecord.getDataID(record);
var previousValue = RelayModernRecord.getValue(record, storageKey);
warning(
storageKey === TYPENAME_KEY ||
previousValue === undefined ||
previousValue === fieldValue,
'RelayResponseNormalizer: Invalid record. The record contains two ' +
'instances of the same id: `%s` with conflicting field, %s and its values: %s and %s.' +
'If two fields are different but share' +
'the same id, one field will overwrite the other.',
dataID,
storageKey,
previousValue,
fieldValue,
);
}
}

/**
* Warns if a single response contains conflicting fields with the same id
*/
_validateConflictingLinkedFieldsWithIdenticalId(
record: Record,
prevID: ?DataID,
nextID: DataID,
storageKey: string,
): void {
if (__DEV__) {
warning(
prevID === undefined || prevID === nextID,
'RelayResponseNormalizer: Invalid record. The record contains ' +
'references to the conflicting field, %s and its id values: %s and %s. ' +
'We need to make sure that the record the field points ' +
'to remains consistent or one field will overwrite the other.',
storageKey,
prevID,
nextID,
);
}
}
}

const instrumentedNormalize: typeof normalize = RelayProfiler.instrument(
Expand Down
Loading

0 comments on commit 87520d3

Please sign in to comment.