web: format the stream_request_body TypeError message with the class#3682
Draft
HrachShah wants to merge 3 commits into
Draft
web: format the stream_request_body TypeError message with the class#3682HrachShah wants to merge 3 commits into
HrachShah wants to merge 3 commits into
Conversation
added 3 commits
July 5, 2026 12:06
These two raise statements pass extra positional arguments to `ValueError` but use only the format string as the first argument, so the result is a tuple of (format_string, arg) instead of the formatted message. str(exc) then shows the literal format string rather than the intended text. Use string formatting to produce a single formatted message, matching the pattern used everywhere else in the codebase. Affected paths: - web.RequestHandler.xsrf_token: unknown xsrf cookie version %d - WebSocketProtocol13._process_server_headers: unsupported extension %r
bind_unix_socket raised ValueError('File %s exists and is not a socket', file)
and _HTTPConnection.run raised ValueError('unsupported auth_mode %s', mode).
Both pass a literal format string and the value as separate arguments, so
str(exc) renders the tuple repr with the format string and the value tucked
into e.args[1] rather than producing a usable error message. Replace with
the formatted single-argument form so the offending file path or mode name
is actually visible to a user reading the traceback or a log line.
Two regression tests:
- tornado/test/netutil_test.py::TestBindUnixSocket::
test_existing_non_socket_file_message_includes_path creates a regular file
where bind_unix_socket expects a socket, captures the leaked fd from the
error path, and asserts the path and 'exists and is not a socket' appear
in str(exc) with a single-arg ValueError.
- tornado/test/httpclient_test.py::HTTPClientCommonTestCase::
test_unsupported_auth_mode_message_format fetches /auth with auth_mode=
'asdf' against the simple client and asserts the 'asdf' literal appears in
the raised ValueError and '%s' does not.
stream_request_body and _has_stream_request_body used the two-argument form
raise TypeError("expected subclass of RequestHandler, got %r", cls)
which stores the format string and class as a tuple in e.args. str(e)
became the tuple repr
"('expected subclass of RequestHandler, got %r', <class '...'>)"
with the literal "%r" placeholder visible and the class tucked into
e.args[1]. The user-visible message did not mention RequestHandler or the
class, and any assertRaisesRegex over the formatted string failed.
Format the message before raising so str(e) is a single, formatted string
that names both the expected type and the offending class.
Add StreamRequestBodyTypeErrorTest with two regression guards that assert
the formatted message contains the class name, does not contain the
"%r" placeholder, and that e.args[0] is the same string as str(e). On
pre-fix code both fail with the literal "%r" placeholder visible.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
stream_request_body and _has_stream_request_body used the two-argument form
which stores the format string and class as a tuple in e.args. str(e) became the tuple repr
with the literal "%r" placeholder visible and the class tucked into e.args[1]. The user-visible message did not mention RequestHandler or the class, and any assertRaisesRegex over the formatted string failed.
Format the message before raising so str(e) is a single, formatted string that names both the expected type and the offending class.
Affects both stream_request_body (the public class decorator) and _has_stream_request_body (the internal helper used in HTTPMessageDelegate.data_received and _GzipMessageDelegate). Same one-line fix in two places.
Tests: StreamRequestBodyTypeErrorTest in tornado/test/web_test.py with two regression guards. Each asserts the formatted message contains the class name, does not contain the "%r" placeholder, and that e.args[0] equals str(e). On pre-fix code both fail with the literal "%r" placeholder visible.
Drafted with Zo Computer MiniMax M3; reviewed by HrachShah.