Skip to content
This repository has been archived by the owner on Feb 21, 2023. It is now read-only.

ConnectionResetError: [WinError 10054] 远程主机强迫关闭了一个现有的连接。 #1121

Closed
RonaldinhoL opened this issue Sep 6, 2021 · 12 comments · Fixed by x0day/aioredis-py#1 or #1129

Comments

@RonaldinhoL
Copy link

RonaldinhoL commented Sep 6, 2021

idk what happend, but it dosen't work suddenly.
i guarantee redis server is ok and i try other redis lib it works too,

i am use version:
aioredis==2.0.0

  • async-timeout [required: Any, installed: 3.0.1]
  • typing-extensions [required: Any, installed: 3.10.0.2]

on Microsoft Windows [Version 10.0.19043.1165]
python 3.9.6

@RonaldinhoL
Copy link
Author

RonaldinhoL commented Sep 6, 2021

the error stack is :

Traceback (most recent call last):
  File "c:\users\ronaldinho\.pyenv\pyenv-win\versions\3.9.6\lib\asyncio\runners.py", line 44, in run
    return loop.run_until_complete(main)
  File "c:\users\ronaldinho\.pyenv\pyenv-win\versions\3.9.6\lib\asyncio\base_events.py", line 642, in run_until_complete
    return future.result()
  File "E:/xxx.py", line 14, in main
    for sessionid in await redis.keys("session*"):
  File "C:\Users\Ronaldinho\.virtualenvs\xxx-5Vbn2Ffj\lib\site-packages\aioredis\client.py", line 1064, in execute_command
    return await self.parse_response(conn, command_name, **options)
  File "C:\Users\Ronaldinho\.virtualenvs\xxx-5Vbn2Ffj\lib\site-packages\aioredis\client.py", line 1080, in parse_response
    response = await connection.read_response()
  File "C:\Users\Ronaldinho\.virtualenvs\xxx-5Vbn2Ffj\lib\site-packages\aioredis\connection.py", line 854, in read_response
    response = await self._parser.read_response()
  File "C:\Users\Ronaldinho\.virtualenvs\xxx-5Vbn2Ffj\lib\site-packages\aioredis\connection.py", line 367, in read_response
    raw = await self._buffer.readline()
  File "C:\Users\Ronaldinho\.virtualenvs\xxx-5Vbn2Ffj\lib\site-packages\aioredis\connection.py", line 301, in readline
    await self._read_from_socket()
  File "C:\Users\Ronaldinho\.virtualenvs\xxx-5Vbn2Ffj\lib\site-packages\aioredis\connection.py", line 247, in _read_from_socket
    data = await self._stream.read(self.socket_read_size)
  File "c:\users\ronaldinho\.pyenv\pyenv-win\versions\3.9.6\lib\asyncio\streams.py", line 684, in read
    await self._wait_for_data('read')
  File "c:\users\ronaldinho\.pyenv\pyenv-win\versions\3.9.6\lib\asyncio\streams.py", line 517, in _wait_for_data
    await self._waiter
  File "c:\users\ronaldinho\.pyenv\pyenv-win\versions\3.9.6\lib\asyncio\selector_events.py", line 856, in _read_ready__data_received
    data = self._sock.recv(self.max_size)
ConnectionResetError: [WinError 10054] 远程主机强迫关闭了一个现有的连接。
python-BaseException

Process finished with exit code 1

@rushilsrivastava
Copy link

See #778.

@eneloop2
Copy link

eneloop2 commented Sep 9, 2021

Hi all, the problem lies with the ConnectionError type. aioredis implements its own ConnectionError(builtins.ConnectionError, RedisError which causes problems because ConnectionResetError is no longer a subclass of ConnectionError. If one looks at line 37 of client.py, it overwrites ConnectionError so that the exception can no longer be caught on line 1067....

@Andrew-Chen-Wang
Copy link
Collaborator

@eneloop2 please create a PR or gist to demonstrate the fix. Greatly appreciated investigation!

@eneloop2
Copy link

Hey @Andrew-Chen-Wang, I'm not sure how you guys want to fix it since I'm not sure about the motivation behind subclassing builtins.ConnectionError and RedisError. It would be better to just check if the exception is one of builtins.ConnectionError, RedisError instead. perhaps you can shed some light on that.

@Andrew-Chen-Wang
Copy link
Collaborator

@eneloop2 this is just a port from redis-py, so the only original motivation behind it was that we copied code. Besides that, I guess it would make more sense to solely subclass RedisError as a specific exception to our library.

@seandstewart
Copy link
Collaborator

This is incorrect - with multiple inheritance, a class is a subclass of both parent classes.

class MyException(Exception): ...

class SomeException(ConnectionError, MyException): ...


print(issubclass(SomeException, ConnectionError))
print(issubclass(SomeException, MyException))

try:
    raise SomeException("ack!")
except MyException as e:
    print(e)

try:
    raise SomeException("agh!")
except ConnectionError as e:
    print(e)

#> True
#> True
#> ack!
#> agh!

@eneloop2
Copy link

No, your example is wrong. Because that's not how ConnectionError is defined in the aioredis.

@eneloop2
Copy link

This is incorrect - with multiple inheritance, a class is a subclass of both parent classes.

class MyException(Exception): ...

class SomeException(ConnectionError, MyException): ...


print(issubclass(SomeException, ConnectionError))
print(issubclass(SomeException, MyException))

try:
    raise SomeException("ack!")
except MyException as e:
    print(e)

try:
    raise SomeException("agh!")
except ConnectionError as e:
    print(e)

#> True
#> True
#> ack!
#> agh!

Look and see which ConnectionError is being handled in the aioredis code. Of course SomeException is an instance of MyException. But aioredis ConnectionError is ConnectionError(builtins.ConnectionError, RedisError). Later, there's code that does from exceptions import ConnectionError .... At that point it's been re-written. Run it through the code and see for yourself. It's quite obvious.

@eneloop2
Copy link

from aioredis.exceptions import ConnectionError

try:
  raise ConnectionResetError("bad!!")
except ConnectionError:
  print("not bad!")

What does this print? This is exactly what's going on in aioredis/connection.py, it does from .exceptions import ConnectionError.

@x0day
Copy link
Contributor

x0day commented Sep 16, 2021

@Andrew-Chen-Wang maybe you should look this issue and patch from redis-py project.

and try this demo.

from aioredis.connection import NONBLOCKING_EXCEPTIONS

try:
    raise ConnectionResetError
except NONBLOCKING_EXCEPTIONS:
    print('aioredis catched!')
except Exception as exc:
    print("aioredis not catched!")

from redis.connection import NONBLOCKING_EXCEPTIONS

try:
    raise ConnectionResetError
except NONBLOCKING_EXCEPTIONS:
    print('redis-py catched')

output:

aioredis not catched!
redis-py catched

add socket.error in NONBLOCKING_EXCEPTIONS is not only for Python 2/3 compatible, please fix it, thanks.

x0day added a commit to x0day/aioredis-py that referenced this issue Sep 16, 2021
@rushilsrivastava
Copy link

For an updated reference to the commit, see redis/redis-py@f0516c9.

I think this was not ported over in the migration and should be. @Andrew-Chen-Wang can we get #1129 in the #1156 update PR?

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants