@@ -414,6 +414,24 @@ async def _make_subprocess_transport(self, protocol, args, shell,
414414 return transp
415415
416416
417+ def overlapped_connection_reset_error_handler (func ):
418+ """
419+ Rethrow common connection errors that come from clients
420+ disconnecting unexpectedly. This is a common error that
421+ can be safely ignored in most cases.
422+ """
423+ def wrapper (* args , ** kwargs ):
424+ try :
425+ return func (* args , ** kwargs )
426+ except OSError as exc :
427+ if exc .winerror in (_overlapped .ERROR_NETNAME_DELETED ,
428+ _overlapped .ERROR_OPERATION_ABORTED ):
429+ raise ConnectionResetError (* exc .args )
430+ else :
431+ raise
432+ return wrapper
433+
434+
417435class IocpProactor :
418436 """Proactor implementation using IOCP."""
419437
@@ -458,15 +476,9 @@ def _result(self, value):
458476 return fut
459477
460478 @staticmethod
479+ @overlapped_connection_reset_error_handler
461480 def finish_socket_func (trans , key , ov ):
462- try :
463- return ov .getresult ()
464- except OSError as exc :
465- if exc .winerror in (_overlapped .ERROR_NETNAME_DELETED ,
466- _overlapped .ERROR_OPERATION_ABORTED ):
467- raise ConnectionResetError (* exc .args )
468- else :
469- raise
481+ return ov .getresult ()
470482
471483 @classmethod
472484 def _finish_recvfrom (cls , trans , key , ov , * , empty_result ):
@@ -552,6 +564,7 @@ def accept(self, listener):
552564 ov = _overlapped .Overlapped (NULL )
553565 ov .AcceptEx (listener .fileno (), conn .fileno ())
554566
567+ @overlapped_connection_reset_error_handler
555568 def finish_accept (trans , key , ov ):
556569 ov .getresult ()
557570 # Use SO_UPDATE_ACCEPT_CONTEXT so getsockname() etc work.
@@ -596,6 +609,7 @@ def connect(self, conn, address):
596609 ov = _overlapped .Overlapped (NULL )
597610 ov .ConnectEx (conn .fileno (), address )
598611
612+ @overlapped_connection_reset_error_handler
599613 def finish_connect (trans , key , ov ):
600614 ov .getresult ()
601615 # Use SO_UPDATE_CONNECT_CONTEXT so getsockname() etc work.
@@ -628,6 +642,7 @@ def accept_pipe(self, pipe):
628642 # completion of the connection.
629643 return self ._result (pipe )
630644
645+ @overlapped_connection_reset_error_handler
631646 def finish_accept_pipe (trans , key , ov ):
632647 ov .getresult ()
633648 return pipe
0 commit comments