-
-
Notifications
You must be signed in to change notification settings - Fork 9.3k
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
Limit size of payload in JSONDecodeError #6036
Conversation
Is the problem that it gets included in the string representation or that it's included? If it's the former, I'm far more inclined to just not show it there. |
Mostly the fact that it is in the string representation. We could just override that in the class. Or we could make the doc a kwarg that we pop like response. The actual args for IOError are |
0187a17
to
24540e3
Compare
Here's an alternative the just reverses the init order so that the message comes from the base json decode error rather than the ioerror |
Thanks @chyzzqo2, let's see how the tests run. I think this is closer to the right approach. |
Alright tests look good and I did some quick spot checking with the script below. This seems to be relatively in-line with previous behavior (2.26.0). We're no longer mis-populating fields. We do have a number of new unpopulated fields from the multi-inheritance but I don't think that's a deal breaker for now. We'll consider this change a bugfix. If there's enough demand, we may choose to write something to appropriately populate all of the exception metadata later based on which import platform
import requests
print(requests.__version__)
print(platform.python_version())
r = requests.get('https://www.python.org/psf/')
try:
r.json()
except Exception as e:
attributes = [i for i in dir(e) if not i.startswith('_')]
print('Attributes: {}'.format(attributes))
if hasattr(e, 'doc'):
err = "Error Type: {}, Doc type: {}, Doc len: {}"
print(err.format(type(e), type(e.doc), len(e.doc)))
else:
print("No doc attribute present.")
print(e) Requests 2.26.0Python 3.6 (stdlib)
Python 3.6 (simplejson)
Python 3.10 (std lib)
Python 3.10 (simplejson)
Requests (PR #6036)Python 3.6 (std lib)
Python 3.6 (simplejson)
Python 3.10 (std lib)
Python 3.10 (simplejson)
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are there any tests we can add to verify this doesn't revert back to containing the entirety of doc
in the __repr__
? It's also unclear how this prevents that from happening on a visual inspection
1a0b870
to
7f02d09
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Left a few small notes but I think we're close to wrapping this up if @sigmavirus24 doesn't have more concerns.
tests/test_requests.py
Outdated
assert isinstance(excinfo.value, RequestException) | ||
assert isinstance(excinfo.value, JSONDecodeError) | ||
assert data not in str(excinfo.value) | ||
if is_py3: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also somewhat of a nit. It may be better to just make this its own test with a @unittest.skipIf(not is_py3)
at the top.
e.g.
@unittest.skipIf(not is_py3)
def test_json_decode_persists_doc_attr(self, httpbin):
r = requests.get(httpbin('bytes/20'))
with pytest.raises(requests.exceptions.JSONDecodeError) as e:
r.json()
assert e.doc == r.text
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
don't we want to test that the py2 object is also what we expect? Or if we don't can i can make it py3 only?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The original test doesn't assert anything about Python 2 either. So we don't lose anything with this change. I suppose we could assert doc isn't on the Python 2 exception but I'm not sure how meaningful that is.
Edit: to be clear I'm proposing two tests. The one you have and moving the Python 3 specifics to its own test.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok, i think i updated it with what you had in mind.
42b1864
to
045a8c5
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great, thanks for the updates @chyzzqo2! I think there were a couple more things we discussed in the last review I left comments on. Let me know if you have any questions.
That way we get the formated error message
045a8c5
to
e3f7e57
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me, thanks @chyzzqo2!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems good to me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm still not convinced this is maintainable or correct but I also understand that it's probably a tonne of work to get compatibility on python 2 and 3 that isn't a scary nightmare
Sigmavirus24 rereviewed but GH is still blocking on original change request :/
This will be fixed in requests as well, see psf/requests#6036 Fixes WEBLATE-8XX
Also require "requests>=2.28.0" to avoid excessive JSONDecodeError message size (psf/requests#6036)
Hello! I'm facing an issue now (after upgrading to Basically, I want to test the
Anything we should be concerned about at this point, after the PR is released? Or is there something I do wrong? |
Hi @mykolasolodukha, Being able to create an empty JSONDecodeError wasn't originally intended when implementing this error. The function signature was kept ambiguous due to differences between Python2/3 and these exceptions generally aren't intended to be reused externally. We may be able to make the signature more explicit now but in the interim, you can instantiate the error similar to below:
The stdlib JSONDecodeError takes argument types |
Thanks a lot @nateprewitt ! |
2.27 introduced a change in behavior where now the exception raised by parsing invalid data as json contains the full body of the invalid response. This gets included it's string representation. This can cause problems when the response is very large. This PR tries to limit the size of the response that we store this way, to what might be around the reported error position. But we could also just return to first n bytes or remove the response altogether and let users fetch it, if needed from the error.response object.