When you develop on OS X, and start Plone 5.2 in foreground with PDBDebugMode activated, you ocassionally can see the following error:
2021-02-11 22:58:18,907 ERROR [waitress:121][MainThread] Socket error Traceback (most recent call last): File "/Users/fred/.buildout/eggs/waitress-1.4.4-py3.8.egg/waitress/channel.py", line 118, in handle_write flush() File "/Users/fred/.buildout/eggs/waitress-1.4.4-py3.8.egg/waitress/channel.py", line 227, in _flush_some num_sent = self.send(chunk) File "/Users/fred/.buildout/eggs/waitress-1.4.4-py3.8.egg/waitress/wasyncore.py", line 433, in send result = self.socket.send(data) OSError: [Errno 41] Protocol wrong type for socket [Errno 41] Protocol wrong type for socket
Which is very annoying because it seems to be random and it throws you into a pdb where you have to continue first to get started. It's easy to ignore, but still mosquito iritating, you keep waving your hands :-(. I did some searching yesterday and it's reported by other communities as well, not limited to Python, but specific for OS X
The most thorough explanation IMHO was written by a Rust developer in 2014:
If I understand his blog post correctly its an edge case where OS X return a wrong code when a socket is being closed but some data is still sent. His solution in Rust at the end of the article is something I think we can apply 1:1 to Python/Waitress.
It's this method in waitress wasyncore.py:
If you import EPROTOTYPE as well from errno (imports at the top of wasyncore.py) and add the two commented lines below, you just ignore it.
Maybe instead of
return 0 would be better. After I added this locally, the random Pdb's so far have stopped.
def send(self, data): try: result = self.socket.send(data) return result except socket.error as why: if why.args == EWOULDBLOCK: return 0 elif why.args in _DISCONNECTED: self.handle_close() return 0 #elif why.args == EPROTOTYPE: # pass else: raise