Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 14 additions & 7 deletions src/graphql/validation/validate.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

from __future__ import annotations

from typing import TYPE_CHECKING
from typing import TYPE_CHECKING, Any

from ..error import GraphQLError
from ..language import DocumentNode, ParallelVisitor, visit
Expand All @@ -29,10 +29,17 @@
class ValidationAbortedError(GraphQLError):
"""Error when a validation has been aborted (error limit reached)."""

def __init__(
self,
message: str = (
"Too many validation errors, error limit reached. Validation aborted."
),
**kwargs: Any,
) -> None:
super().__init__(message, **kwargs)

validation_aborted_error = ValidationAbortedError(
"Too many validation errors, error limit reached. Validation aborted."
)

validation_aborted_error = ValidationAbortedError()


# Per the specification, descriptions must not affect validation.
Expand Down Expand Up @@ -113,7 +120,7 @@ def validate(

def on_error(error: GraphQLError) -> None:
if len(errors) >= max_errors:
raise validation_aborted_error
raise ValidationAbortedError
errors.append(error)

context = ValidationContext(
Expand All @@ -131,8 +138,8 @@ def on_error(error: GraphQLError) -> None:
TypeInfoVisitor(type_info, ParallelVisitor(visitors)),
query_document_keys_to_validate,
)
except ValidationAbortedError:
errors.append(validation_aborted_error)
except ValidationAbortedError as error:
errors.append(error.with_traceback(None))
return errors


Expand Down
11 changes: 11 additions & 0 deletions tests/validation/test_validation.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from graphql.language import parse
from graphql.utilities import build_schema
from graphql.validation import ValidationRule, validate
from graphql.validation.validate import ValidationAbortedError, validation_aborted_error

from .harness import test_schema

Expand Down Expand Up @@ -136,6 +137,16 @@ def enter_field(self, *_args):
with pytest.raises(RuntimeError, match=r"^Error from custom rule!$"):
validate(test_schema, doc, [CustomRule], max_errors=1)

def does_not_accumulate_traceback_on_aborted_error():
first_error = _validate_document(max_errors=1)[-1]
second_error = _validate_document(max_errors=1)[-1]
assert isinstance(first_error, ValidationAbortedError)
assert isinstance(second_error, ValidationAbortedError)
assert first_error is not second_error
assert first_error.__traceback__ is None
assert second_error.__traceback__ is None
assert validation_aborted_error.__traceback__ is None


def describe_operation_and_variable_definition_descriptions():
def validates_operation_with_description_and_variable_descriptions():
Expand Down