-
-
Notifications
You must be signed in to change notification settings - Fork 9.5k
Streaming requests should raise an error when network problems occur #857
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
Comments
See also #844. |
I'd quite happily have a go at implementing a fix for this myself, if someone more familiar with the codebase could give me a few pointers of where to start? |
Check out From my cursory inspection of the code, it's actually surprising to me that socket errors from these Do you have a test case for the issue? Thanks for the bug report and the offer of a patch, always appreciated :-) Tell us if we can offer any more guidance. |
Good to know that this issue has some attention. Just for the moment, what would be the best way to handle server side or client side HTTP errors when streaming? The current approach I'm using now. I don't know if it's going to work though, as I'm not sure whether r = request.get(url, ...)
while r.status_code >= 200 and r.status_code <= 299:
for line in r.iter_lines(chunk_size=chunk_size):
if line:
# do great things
else:
# handle potential HTTP errors And furthermore, how do I appropriately implement retry logic in this case? |
@ruli look at I think there is retry logic recipe (in general) in the docs written as a hook. I'm not 100% sure though. Hope this gives you a hand. |
Ah, alright. So the hook would give me a timely update on the status? I'm checking the docs and haven't seen it mentioned though. And my impression is that if I attempt to retrieve the headers, then the connection is automagically closed even if no error (server/client side) has occured. Right now I'll just use a naive way: try:
while 1:
r = requests.get(url, ..., prefetch=False)
if r.status_code == 200:
for line in r.iter_lines():
if line:
# do greatness
else:
# log
# exponential or fixed time.sleep(x)
except ... # Major nastiness happened, we may not see 2013 coming This use case is used primarily for (theoretically) endless HTTP streams. |
For a stream with an expected rate of responses, it is probably best to set a sanity The TCP does have the concept of keep alive. This can be enabled with |
@jkl1337 we don't set the options on the sockets and I'm not sure if urllib3 does either (although if it does, it would probably be a good idea to submit the idea to @shazow). That aside, it would be ideal if we could use We could definitely catch and re-throw the |
There is already a timeout parameter available for the The solution to the original post I believe is to just use an appropriate timeout argument to requests. That said, there might be an API defect in how the exceptions are handled (though they still come through): Of course, the same will occur for the streaming case. A raw socket.error or socket.timeout will be propagated. So I am not yet sure what is the intent of the translation in The exact tests I used were an HTTP server that returns a Content-Length greater than the amount of data sent before a long pause (no FIN sent) and also an immediate |
It seems streaming requests (as per example given here) do not raise an error when the connection is dropped or when there are network problems that prevent the stream from being consumed. This makes it difficult to know if we should reconnect to the stream.
If an error was raised, then disconnections could be handled gracefully, e.g.
The text was updated successfully, but these errors were encountered: