Skip to content

Commit

Permalink
Derive @required fieldPath at runtime
Browse files Browse the repository at this point in the history
Reviewed By: lynnshaoyu

Differential Revision: D65459456

fbshipit-source-id: a6e4788a7fa979a8b3ce5c19781b9390d9d9fd59
  • Loading branch information
captbaritone authored and facebook-github-bot committed Nov 11, 2024
1 parent 7c9aebb commit a88c013
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 15 deletions.
35 changes: 23 additions & 12 deletions packages/relay-runtime/store/RelayReader.js
Original file line number Diff line number Diff line change
Expand Up @@ -295,31 +295,42 @@ class RelayReader {
return this._variables[name];
}

_maybeReportUnexpectedNull(fieldPath: string, action: 'LOG' | 'THROW') {
_maybeReportUnexpectedNull(selection: ReaderRequiredField) {
if (selection.action === 'NONE') {
return;
}
const owner = this._fragmentName;

if (this._errorResponseFields == null) {
this._errorResponseFields = [];
}

switch (action) {
let fieldName: string;
if (selection.field.linkedField != null) {
fieldName =
selection.field.linkedField.alias ?? selection.field.linkedField.name;
} else {
fieldName = selection.field.alias ?? selection.field.name;
}

switch (selection.action) {
case 'THROW':
this._errorResponseFields.push({
kind: 'missing_required_field.throw',
fieldPath,
fieldPath: fieldName,
owner,
handled: false,
});
return;
case 'LOG':
this._errorResponseFields.push({
kind: 'missing_required_field.log',
fieldPath,
fieldPath: fieldName,
owner,
});
return;
default:
(action: empty);
(selection.action: empty);
}
}

Expand All @@ -328,10 +339,7 @@ class RelayReader {
value: mixed,
): boolean /*should continue to siblings*/ {
if (value == null) {
const {action} = selection;
if (action !== 'NONE') {
this._maybeReportUnexpectedNull(selection.path, action);
}
this._maybeReportUnexpectedNull(selection);
// We are going to throw, or our parent is going to get nulled out.
// Either way, sibling values are going to be ignored, so we can
// bail early here as an optimization.
Expand Down Expand Up @@ -1137,8 +1145,9 @@ class RelayReader {
* Similarly, when creating field errors, we simply initialize the `fieldPath`
* as the direct field name.
*
* Today we only use this apporach for `missing_expected_data` errors, but we
* intend to broaden it to handle all field error paths.
* Today we only use this apporach for `missing_expected_data` and
* `missing_required_field` errors, but we intend to broaden it to handle all
* field error paths.
*/
_prependPreviousErrors(
prevErrors: ?Array<ErrorResponseField>,
Expand All @@ -1150,7 +1159,9 @@ class RelayReader {
if (
event.owner === this._fragmentName &&
(event.kind === 'missing_expected_data.throw' ||
event.kind === 'missing_expected_data.log')
event.kind === 'missing_expected_data.log' ||
event.kind === 'missing_required_field.throw' ||
event.kind === 'missing_required_field.log')
) {
event.fieldPath = `${fieldNameOrIndex}.${event.fieldPath}`;
}
Expand Down
4 changes: 2 additions & 2 deletions packages/relay-runtime/store/RelayStoreTypes.js
Original file line number Diff line number Diff line change
Expand Up @@ -1311,7 +1311,7 @@ export type MissingExpectedDataThrowEvent = {
export type MissingRequiredFieldLogEvent = {
+kind: 'missing_required_field.log',
+owner: string,
+fieldPath: string,
fieldPath: string, // Purposefully mutable to allow lazy construction in RelayReader
};

/**
Expand All @@ -1328,7 +1328,7 @@ export type MissingRequiredFieldLogEvent = {
export type MissingRequiredFieldThrowEvent = {
+kind: 'missing_required_field.throw',
+owner: string,
+fieldPath: string,
fieldPath: string, // Purposefully mutable to allow lazy construction in RelayReader
+handled: boolean,
};

Expand Down
3 changes: 2 additions & 1 deletion packages/relay-runtime/util/ReaderNode.js
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,8 @@ export type ReaderRequiredField = {
+kind: 'RequiredField',
+field: ReaderField | ReaderClientEdge,
+action: RequiredFieldAction,
+path: string,
// TODO: This field is not used any more, we should be able to remove it.
+path?: mixed,
};

export type CatchFieldTo = 'RESULT' | 'NULL';
Expand Down

0 comments on commit a88c013

Please sign in to comment.