Thanks to visit codestin.com
Credit goes to github.com

Skip to content

ThreadException: ConnectionResetError: [Errno 104] #2342

@kon-mtal

Description

@kon-mtal

Due diligence
Please try searching the issue tracker for your problem if you haven't already!
If you find related issues that aren't an exact match, feel free to continue
making a report, and link to those issues.

Describe the bug
A clear and concise description of what the bug is.

ThreadException (ConnectionResetError: [Errno 104]) when exiting a Connection.forward_local() context manager

To Reproduce
Steps to reproduce the behaviour (please attach a minimal example):

  1. Setup a connection in the following fashion:
connection = Connection(
        host=hostname,
        connect_kwargs={"pkey": pkey, "look_for_keys": False},
    )
  1. Set up a context manager like so:
with connection.forward_local(local_port=10014, remote_port=9005):
  1. Inside of the context manager, interact with a browser using async Playwright. Create two pages, navigate through some locators.
  2. Close the Playwright pages, browser and async Playwright using the .close() and .stop() methods (verified using print and sleep that the error occurs after all has been closed)
  3. Have the context manager exit normally after leaving its indentation

Expected behaviour
The context manager exits gracefully and no ThreadException is raised.

Environment
Make sure your report gets the attention it deserves: bug reports with missing
information may be ignored or punted back to you, delaying a fix. The below
constitutes a bare minimum; more info is almost always better:

  • What version of the Python interpreter are you using? Are you using an
    alternative interpreter such as PyPy?
    Python 3.11.9 through IPython 8.17.2
  • What operating system are you using both client & server-side?
    Client: AlmaLinux 9.5 (Teal Serval)
    Server: Red Hat Enterprise Linux 9.5 (Plow)
  • Are you using OpenSSH server or something else?
    Yes, OpenSSH_8.7p1
  • Which version or versions of the software are you using?
    fabric==3.2.2, paramiko==3.3.1
    • Have you already tried the latest release?
      No
    • Have you, or can you, try some older releases to pin down where the bug
      appeared?
      I have not tried
  • How can the developers recreate the bug on their end? If possible, include a
    copy of your code, the command you used to invoke it, and the full output of
    your run (if applicable.)
File ~/repo_tool/system/tests/web_ui/file.py:458, in main()
    455     LOCAL_FORWARDED_PORT = 10014
    457 # .forward_local needs to be a context man.
--> 458 with connection.forward_local(local_port=LOCAL_FORWARDED_PORT, remote_port=9005):
    459     webui = WebUI(
    460         "user",
    461         "password",
   (...)
    464         ignore_https=True,
    465     )
    466     await webui.start()

File /usr/lib64/python3.11/contextlib.py:144, in _GeneratorContextManager.__exit__(self, typ, value, traceback)
    142 if typ is None:
    143     try:
--> 144         next(self.gen)
    145     except StopIteration:
    146         return False

File ~/repo_tool/repo_tool_venv/lib64/python3.11/site-packages/fabric/connection.py:1003, in Connection.forward_local(self, local_port, remote_port, remote_host, local_host)
   1001 if wrapper is not None:
   1002     if wrapper.type is ThreadException:
-> 1003         raise wrapper.value
   1004     else:
   1005         raise ThreadException([wrapper])

File ~/repo_tool/repo_tool_venv/lib64/python3.11/site-packages/invoke/util.py:209, in ExceptionHandlingThread.run(self)
    188 try:
    189     # Allow subclasses implemented using the "override run()'s body"
    190     # approach to work, by using _run() instead of run(). If that
    191     # doesn't appear to be the case, then assume we're being used
    192     # directly and just use super() ourselves.
    193     # XXX https://github.com/python/mypy/issues/1424
    194     if hasattr(self, "_run") and callable(self._run):  # type: ignore
    195         # TODO: this could be:
    196         # - io worker with no 'result' (always local)
   (...)
    207         # - assume the run/sudo/etc case will use a queue inside its
    208         # worker body, orthogonal to how exception handling works
--> 209         self._run()  # type: ignore
    210     else:
    211         super().run()

File ~/repo_tool/repo_tool_venv/lib64/python3.11/site-packages/fabric/tunnels.py:102, in TunnelManager._run(self)
    100 # Handle exceptions
    101 if exceptions:
--> 102     raise ThreadException(exceptions)
    104 # All we have left to close is our own sock.
    105 # TODO: use try/finally?
    106 sock.close()
  • A common tactic is to pare down your code until a simple (but still
    bug-causing) “base case” remains. Not only can this help you identify
    problems which aren’t real bugs, but it means the developer can get to fixing
    the bug faster.

Additional context
Add any other context about the problem here.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions