This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: Catch FileNotFoundError in socketserver.DatagramRequestHandler
Type: behavior Stage:
Components: Library (Lib) Versions: Python 3.10
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: berker.peksag, desbma, martin.panter
Priority: normal Keywords: patch

Created on 2016-02-21 19:28 by desbma, last changed 2022-04-11 14:58 by admin.

Files
File name Uploaded Description Edit
server_dgram.py desbma, 2016-02-21 19:28 Unix Domain socket server in datagram mode to reproduce
issue26403.patch desbma, 2016-02-21 19:30 First minimal patch review
issue26403_v2.patch desbma, 2016-02-22 20:54 Catch and ignore FileNotFoundError exception review
Messages (5)
msg260632 - (view) Author: desbma (desbma) * Date: 2016-02-21 19:28
When using socketserver to create a simple server for Unix Domain sockets (see server_dgram.py), and when sending data with a client that immediately shuts down (without waiting for a response, on Linux I test with 'echo data | nc -Uu -w 0 /tmp/s.socket')  I get this exception:

Exception happened during processing of request from /tmp/nc.XXXXsuGc1C
Traceback (most recent call last):
  File "/usr/lib/python3.4/socketserver.py", line 617, in process_request_thread
    self.finish_request(request, client_address)
  File "/usr/lib/python3.4/socketserver.py", line 344, in finish_request
    self.RequestHandlerClass(request, client_address, self)
  File "/usr/lib/python3.4/socketserver.py", line 675, in __init__
    self.finish()
  File "/usr/lib/python3.4/socketserver.py", line 752, in finish
    self.socket.sendto(self.wfile.getvalue(), self.client_address)
FileNotFoundError: [Errno 2] No such file or directory

The attached patch fixes this by checking if there is something to send before calling sendto.

Also I am wondering if we should catch FileNotFoundError (and possibly other exceptions) here, because with TCP or UDP, the server does not raise any exception if client is disconnected when finish is called in the handler.

Thank you
msg260648 - (view) Author: Berker Peksag (berker.peksag) * (Python committer) Date: 2016-02-21 23:25
This looks like a duplicate of issue 5824. See msg259969 for Martin's analysis in that issue.

There is also a similar patch for 2.7 in issue 1767511: http://bugs.python.org/file9271/DatagramServer.diff
msg260649 - (view) Author: Martin Panter (martin.panter) * (Python committer) Date: 2016-02-21 23:32
This change has already been proposed in Issue 1767511, which I recently replied to. I think it is valid to send an empty datagram back to the client, and not doing so could break existing code.

Also see Issue 5824 about removing the comment about recvfrom() on Linux.

Your FileNotFoundError is caused by the client removing its receiving socket file. This would also occur if the server was trying to send a non-zero datagram.

IMO this is usually an asynchronous error that is beyond the control of the server. In the TCP case, you can get similar errors if the client disconnected (BrokenPipeError, ConnectionResetError, etc). But these “error” conditions might only be detected after the server has closed its socket, which is why you don’t always see them.
msg260665 - (view) Author: Martin Panter (martin.panter) * (Python committer) Date: 2016-02-22 09:56
Actually there is precedent for some asynchronous errors due to the client to be ignored:

* Revision 87d3f91e44d4: Catch socket.error (now OSError) from accept()
* r73819: Catch socket.error (OSError) to handle ENOTCONN from shutdown()
* Revision 7e5d7ef4634d: Catch socket.error from sendall(); apparently Windows decides to locally drop the connection and raises ECONNABORTED

So it might be reasonable to catch FileNotFoundError (ENOENT) from sendto(), for Unix domain datagram servers.
msg260699 - (view) Author: desbma (desbma) * Date: 2016-02-22 20:54
OK, so first part of this issue (sendto called even if no data has been written) is indeed a duplicate of https://bugs.python.org/issue1767511 sorry for that.

For the second part of the issue (the exception not silenced), I have attached a new patch.
History
Date User Action Args
2022-04-11 14:58:27adminsetgithub: 70591
2021-03-22 16:28:50iritkatrielsetversions: + Python 3.10, - Python 3.5
2016-02-22 20:55:30desbmasettitle: Don't call sendto in socketserver.DatagramRequestHandler if there is nothing to send -> Catch FileNotFoundError in socketserver.DatagramRequestHandler
2016-02-22 20:54:21desbmasetfiles: + issue26403_v2.patch

messages: + msg260699
2016-02-22 09:56:15martin.pantersetmessages: + msg260665
2016-02-21 23:32:52martin.pantersetmessages: + msg260649
2016-02-21 23:25:58berker.peksagsetnosy: + berker.peksag, martin.panter, - ronaldoussoren, ned.deily
messages: + msg260648
2016-02-21 20:15:45desbmasettype: behavior
2016-02-21 19:34:44desbmasettitle: Don't call sendto in DatagramRequestHandler if there is nothing to send -> Don't call sendto in socketserver.DatagramRequestHandler if there is nothing to send
2016-02-21 19:30:06desbmasetfiles: + issue26403.patch
keywords: + patch
components: + Library (Lib), - macOS
2016-02-21 19:28:45desbmacreate