Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Return 400 on unknown operation name (version 4) #6652

Merged
merged 9 commits into from
Jul 12, 2022

Conversation

trevor-scheer
Copy link
Member

@trevor-scheer trevor-scheer commented Jul 8, 2022

Specifically handle the cases where an operation couldn't be resolved (either
due to an incorrect operationName or a missing operationName in the
presence of two operations).

In these cases, we know that buildExecutionContext will return a single error
and we know this is a client error. We can end execution and respond with a 400
along with a useful error code and the error from graphql-js.

@changeset-bot
Copy link

changeset-bot bot commented Jul 8, 2022

⚠️ No Changeset found

Latest commit: a0c1bef

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@netlify
Copy link

netlify bot commented Jul 8, 2022

Deploy Preview for apollo-server-docs failed.

Name Link
🔨 Latest commit a0c1bef
🔍 Latest deploy log https://app.netlify.com/sites/apollo-server-docs/deploys/62cdd5474ae77e000950f698

@codesandbox-ci
Copy link

codesandbox-ci bot commented Jul 8, 2022

This pull request is automatically built and testable in CodeSandbox.

To see build info of the built libraries, click here or the icon next to each commit SHA.

Latest deployment of this branch, based on commit a0c1bef:

Sandbox Source
Apollo Server Typescript Configuration
Apollo Server Configuration

return e;
});

if (resultErrors) {
await didEncounterErrors(resultErrors);
}

if (resultErrors?.length && !('data' in result)) {
return await sendErrorResponse(resultErrors);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this calls didEncounterErrors, so we don't want to do that twice.

also this doesn't call executionDidEnd? that seems wrong?

@@ -75,6 +76,10 @@ function isBadUserInputGraphQLError(error: GraphQLError): boolean {
);
}

function isUnknownOperationNameError(error: GraphQLError): boolean {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We also need to catch the case where multiple operations are provided but no operation name is given: https://github.com/graphql/graphql-js/blob/ffe37cb7f501e65e445c30764a1b34f659562756/src/execution/execute.ts#L275

(I don't think we need to handle the third error in that function because IIUC this happens if there are no operations in the document, but I think that's a validation error: the parser requires there to be some top-level definition, and ExecutableDefinitionsRule requires all definitions to be operations or fragments. And NoUnusedFragmentsRule requires all fragments to be used (transitively) by an operation.)

That probably means that the name UnknownOperationNameError should change. Maybe to OperationResolveError or OperationResolutionError or something (going with our didResolveOperation hook).

Then um. We could just decide that if requestContext.operation is falsey, we turn any error we get out of execute into an OperationResolutionError, assuming our logic matches that in graphql-js... which I think is probably true.

BTW, if we do want to stick with error string matching, it raises the question of whether the error is precisely the same when execute is gateway or a custom executor... It looks like buildOperationContext in gateway happens to use the same error strings but that's a strong assumption...

(Of course hopefully one day graphql-js will just let us use its operation-resolving code directly, cc @IvanGoncharov.)

@trevor-scheer trevor-scheer force-pushed the trevor/parse-validate-operationName-errors branch from 65fa6bf to 2d7c5f6 Compare July 12, 2022 18:18
@trevor-scheer
Copy link
Member Author

@glasser good comments. Hopefully all addressed via 2d7c5f6.

Your link (https://github.com/graphql/graphql-js/blob/ffe37cb7f501e65e445c30764a1b34f659562756/src/execution/execute.ts#L275) was helpful in deciding to un-fragile the approach a bit, hopefully? Now rather than string matching, I'm assuming there's one expected error from graphql-js. Let me know what you think.

@trevor-scheer trevor-scheer marked this pull request as ready for review July 12, 2022 18:24
extensions: error.extensions,
});

await Promise.all(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe throw the error instead of repeating this (so we never call executionDidEnd twice with errors).

// If we don't have an operation, there's no reason to go further. We know
// `result` will consist of one error (returned by `graphql-js`'s
// `buildExecutionContext`).
if (!requestContext.operation && result.errors?.length) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe throw something different if !operation and !errors

@glasser
Copy link
Member

glasser commented Jul 12, 2022

BTW for posterity: this was a regression on version-4.

@trevor-scheer trevor-scheer merged commit 589aef4 into version-4 Jul 12, 2022
@trevor-scheer trevor-scheer deleted the trevor/parse-validate-operationName-errors branch July 12, 2022 20:13
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Mar 16, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants