Skip to content

Commit c563028

Browse files
committed
improve errors around dots
Replicates graphql/graphql-js@67afee4
1 parent ab2720a commit c563028

2 files changed

Lines changed: 32 additions & 4 deletions

File tree

src/graphql/language/lexer.py

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -144,8 +144,29 @@ def read_next_token(self, start: int) -> Token:
144144
if is_name_start(char):
145145
return self.read_name(position)
146146

147-
if char == "." and body[position + 1 : position + 3] == "..":
148-
return self.create_token(TokenKind.SPREAD, position, position + 3)
147+
if char == ".":
148+
next_char = body[position + 1 : position + 2]
149+
if next_char == ".":
150+
if body[position + 2 : position + 3] == ".":
151+
return self.create_token(
152+
TokenKind.SPREAD, position, position + 3
153+
)
154+
raise GraphQLSyntaxError(
155+
self.source,
156+
position,
157+
"Unexpected '..', did you mean '...'?",
158+
)
159+
if is_digit(next_char):
160+
end = position + 1
161+
while end < body_length and is_digit(body[end]):
162+
end += 1
163+
digits = body[position + 1 : end]
164+
raise GraphQLSyntaxError(
165+
self.source,
166+
position,
167+
f"Invalid number, expected digit before '.'"
168+
f", did you mean '0.{digits}'?",
169+
)
149170

150171
message = (
151172
"Unexpected single quote character ('),"

tests/language/test_lexer.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,9 @@ def skips_whitespace_and_comments():
7373
token = lex_one(",,,foo,,,")
7474
assert token == Token(TokenKind.NAME, 3, 6, 1, 4, "foo")
7575

76+
def reports_unexpected_characters():
77+
assert_syntax_error(".", "Unexpected character: '.'.", (1, 1))
78+
7679
def errors_respect_whitespace():
7780
with pytest.raises(GraphQLSyntaxError) as exc_info:
7881
lex_one("\n\n ~\n")
@@ -454,7 +457,11 @@ def lex_reports_useful_number_errors():
454457
assert_syntax_error(
455458
"1.e1", "Invalid number, expected digit but got: 'e'.", (1, 3)
456459
)
457-
assert_syntax_error(".123", "Unexpected character: '.'.", (1, 1))
460+
assert_syntax_error(
461+
".123",
462+
"Invalid number, expected digit before '.', did you mean '0.123'?",
463+
(1, 1),
464+
)
458465
assert_syntax_error(
459466
"1.A", "Invalid number, expected digit but got: 'A'.", (1, 3)
460467
)
@@ -520,7 +527,7 @@ def lexes_punctuation():
520527
assert lex_one("|") == Token(TokenKind.PIPE, 0, 1, 1, 1, None)
521528

522529
def lex_reports_useful_unknown_character_error():
523-
assert_syntax_error("..", "Unexpected character: '.'.", (1, 1))
530+
assert_syntax_error("..", "Unexpected '..', did you mean '...'?", (1, 1))
524531
assert_syntax_error("~", "Unexpected character: '~'.", (1, 1))
525532
assert_syntax_error("\x00", "Unexpected character: U+0000.", (1, 1))
526533
assert_syntax_error("\b", "Unexpected character: U+0008.", (1, 1))

0 commit comments

Comments
 (0)