Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions pythonFiles/include/blender_vscode/communication.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ def start_debug_server():
debugpy.configure(python=str(python_path))
debugpy.listen(("localhost", port))
break
except OSError:
except (OSError, RuntimeError):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why the RuntimeError error in this PR?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Mateusz-Grzelinski

According to the traceback in the linked issue, a RuntimeError is raised when the specific port is unavailable, so I've updated the code to catch it.

However, I am concerned that RuntimeError is too generic. Catching it might trigger the retry loop for errors unrelated to the port issue. To mitigate this, I suggest adding a maximum retry limit. What do you think?

Copy link
Collaborator

@Mateusz-Grzelinski Mateusz-Grzelinski Nov 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Debugpy itself can produce number of errors

RuntimeError("debugpy.listen() has already been called on this process")
RuntimeError: error spawning debug adapter: [WinError 2] The system cannot find the file specified
RuntimeError: Can't listen for client connections: [Errno 11001] getaddrinfo failed

and also anything that socket.bind can throw: PermissionError, OSError. There might be also subprocess module involved...

I think the original author wanted to catch ONLY the error for repeated use of port. Like this one:

RuntimeError: Can't listen for client connections: [WinError 10048] Only one usage of each socket address (protocol/network address/port) is normally permitted

In summary:

  • definitely do not do this in this PR
  • it is more complicated that you think, see below

I think the intent was:

        except (OSError) as e:
            if e.errno == errno.EADDRINUSE:
                print(f"Port is already in use!")
            pass

But to be honest this will never work because debugpy uses subprocess.Open to listen (WTF?!) and then re-raise the erros in degraded way...

  File "C:\Users\grzel\AppData\Roaming\Blender Foundation\Blender\4.0\scripts\modules\debugpy\server\api.py", line 260, in listen
    raise RuntimeError(str(endpoints["error"]))

so good luck handling that correctly?

So a semi working and very delicate snippen for WINDOWS only would be something like this.

        except (OSError) as e:
            # proper but debugpy calls itself subprocess.Popen so this most likely never work
            if e.errno == errno.EADDRINUSE:
                print(f"Port is already in use!")
            pass
        except RuntimeError as e:
            if str(errno.EADDRINUSE) in str(e):
                print(f"Port is already in use!")

Still requires more work for linux and macos...

Copy link
Author

@unclepomedev unclepomedev Nov 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Mateusz-Grzelinski

Thank you for the detailed explanation! I have just started looking at this code, so I don't have an idea for a fundamental solution yet (since the issue was tagged as a "good first issue", I assume a deep architectural fix isn't expected here).

I can propose the following two approaches. Which would you prefer?

  1. Limit this PR to using ephemeral ports to simply reduce the probability of errors.
  2. Suppress the error only when the error message contains "Can't listen for client connections" combined with either "WinError 10013" or "WinError 10048" (which was the original concern).

pass
return port

Expand Down Expand Up @@ -147,7 +147,7 @@ def send_dict_as_json(data):


def get_random_port():
return random.randint(2000, 10000)
return random.randint(49152, 65535)


def get_blender_port():
Expand Down