Skip to content

Report QueryComplexity variable coercion errors instead of throwing - #1969

Open
ruudk wants to merge 1 commit into
masterfrom
fix/1967-query-complexity-reports-coercion-errors
Open

Report QueryComplexity variable coercion errors instead of throwing#1969
ruudk wants to merge 1 commit into
masterfrom
fix/1967-query-complexity-reports-coercion-errors

Conversation

@ruudk

@ruudk ruudk commented Aug 25, 2026

Copy link
Copy Markdown
Collaborator

DocumentValidator::validate() is documented to return validation errors, and every other rule reports them through the validation context. But QueryComplexity coerces variable values (it needs them to evaluate @include/@Skip and to build arguments for complexityFn) and threw a raw Error when coercion failed. Callers using DocumentValidator directly rather than GraphQL::promiseToExecute() — which sets the variables and wraps everything in try/catch — got an uncaught exception for something that is a plain input problem.

Coercion errors now go to $context->reportError() and complexity analysis is abandoned for the rest of the document: without usable variable values the computed complexity is meaningless, so reporting a max-complexity error on top of it would be misleading, and calling a user-supplied complexityFn with empty arguments could throw. For the same reason getQueryComplexity() is reset to 0, so it cannot hand back the partial sum accumulated before coercion failed.

This also improves the errors themselves. The old code concatenated the messages of all coercion errors into one Error, discarding the source locations; each error is now reported individually with the location of its variable definition, matching what the executor produces for the same bad input.

While here, buildFieldArguments() reuses the per-document coercion cache instead of coercing all variables again for every field that has a complexityFn.

Fixes #1967

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR updates the QueryComplexity validation rule so variable coercion failures are reported as regular validation errors (via the validation context) instead of throwing, bringing it in line with how DocumentValidator::validate() is documented to behave.

Changes:

  • Report variable coercion errors through $context->reportError() and abandon complexity analysis for that document.
  • Reuse the per-document coerced variable cache when building field arguments (avoids re-coercing per field with a complexityFn).
  • Add regression tests covering coercion failures (including multiple errors, error locations, and per-document reset), plus a changelog entry.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

File Description
src/Validator/Rules/QueryComplexity.php Converts coercion failures from thrown exceptions into reported validation errors and stops complexity enforcement when coercion fails.
tests/Validator/QueryComplexityTest.php Adds coverage for coercion-failure behavior (messages, locations, multiple errors, caching/reset semantics).
CHANGELOG.md Documents the fix under Unreleased.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/Validator/Rules/QueryComplexity.php
`DocumentValidator::validate()` is documented to return validation errors,
and every other rule reports them through the validation context. But
`QueryComplexity` coerces variable values (it needs them to evaluate
@include/@Skip and to build arguments for `complexityFn`) and threw a raw
`Error` when coercion failed. Callers using `DocumentValidator` directly
rather than `GraphQL::promiseToExecute()` — which sets the variables and
wraps everything in try/catch — got an uncaught exception for something
that is a plain input problem.

Coercion errors now go to `$context->reportError()` and complexity
analysis is abandoned for the rest of the document: without usable
variable values the computed complexity is meaningless, so reporting a
max-complexity error on top of it would be misleading, and calling a
user-supplied `complexityFn` with empty arguments could throw. For the
same reason `getQueryComplexity()` is reset to 0, so it cannot hand back
the partial sum accumulated before coercion failed.

This also improves the errors themselves. The old code concatenated the
messages of all coercion errors into one `Error`, discarding the source
locations; each error is now reported individually with the location of
its variable definition, matching what the executor produces for the
same bad input.

While here, `buildFieldArguments()` reuses the per-document coercion
cache instead of coercing all variables again for every field that has a
`complexityFn`.

Fixes #1967
@ruudk
ruudk force-pushed the fix/1967-query-complexity-reports-coercion-errors branch from 986d73b to 1d2e49c Compare August 25, 2026 12:37
@ruudk
ruudk requested a lite review from Copilot August 25, 2026 12:38

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated no new comments.

@ruudk
ruudk marked this pull request as ready for review August 25, 2026 12:42
@ruudk
ruudk requested a review from spawnia August 25, 2026 12:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

QueryComplexity throws instead of reporting validation errors

2 participants