Skip to content

Handle BrokenPipeError gracefully when client disconnects during response#41

Closed
Copilot wants to merge 3 commits into
masterfrom
copilot/fix-broken-pipe-error
Closed

Handle BrokenPipeError gracefully when client disconnects during response#41
Copilot wants to merge 3 commits into
masterfrom
copilot/fix-broken-pipe-error

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Jan 7, 2026

When clients disconnect mid-response, BrokenPipeError cascades through wsgiref's error handlers, producing confusing multi-exception tracebacks with TypeError and AttributeError as the handler tries to send error responses over a closed connection.

Changes

  • Catch connection errors at response send: Added exception handler in Application.__request__() for BrokenPipeError, ConnectionResetError, and ConnectionAbortedError when calling response(start_response). Returns empty iterable to cleanly terminate WSGI cycle.

  • Log as info, not error: Client disconnections are expected behavior. Changed from implicit error-level cascading tracebacks to single log.info() message.

try:
    return response(start_response)
except (BrokenPipeError, ConnectionResetError, ConnectionAbortedError) as err:
    log.info("Client disconnected: %s", str(err))
    return ()

This mirrors the existing ConnectionError handling during request processing, but applies to the response phase where wsgiref's own error handling would otherwise fail.

Original prompt

This section details on the original issue you should resolve

<issue_title>BrokenPipe ... better output</issue_title>
<issue_description>```
ERROR: Error for client 10.24.223.248 {handle_error():17}
#012Traceback (most recent call last):
#12 File "/usr/lib/python3.7/wsgiref/handlers.py", line 138, in run
#12 self.finish_response()
#12 File "/usr/lib/python3.7/wsgiref/handlers.py", line 180, in finish_response
#12 self.write(data)
#12 File "/usr/lib/python3.7/wsgiref/handlers.py", line 274, in write
#12 self.send_headers()
#12 File "/usr/lib/python3.7/wsgiref/handlers.py", line 332, in send_headers
#12 self.send_preamble()
#12 File "/usr/lib/python3.7/wsgiref/handlers.py", line 255, in send_preamble
#12 ('Date: %s\r\n' % format_date_time(time.time())).encode('iso-8859-1')
#12 File "/usr/lib/python3.7/wsgiref/handlers.py", line 453, in _write
#12 result = self.stdout.write(data)
#12 File "/usr/lib/python3.7/socketserver.py", line 799, in write
#12 self._sock.sendall(b)
#012BrokenPipeError: [Errno 32] Broken pipe
#12
#012During handling of the above exception, another exception occurred:
#12
#012Traceback (most recent call last):
#12 File "/usr/lib/python3.7/wsgiref/handlers.py", line 141, in run
#12 self.handle_error()
#12 File "/usr/lib/python3.7/wsgiref/handlers.py", line 368, in handle_error
#12 self.finish_response()
#12 File "/usr/lib/python3.7/wsgiref/handlers.py", line 180, in finish_response
#12 self.write(data)
#12 File "/usr/lib/python3.7/wsgiref/handlers.py", line 274, in write
#12 self.send_headers()
#12 File "/usr/lib/python3.7/wsgiref/handlers.py", line 331, in send_headers
#12 if not self.origin_server or self.client_is_modern():
#12 File "/usr/lib/python3.7/wsgiref/handlers.py", line 344, in client_is_modern
#12 return self.environ['SERVER_PROTOCOL'].upper() != 'HTTP/0.9'
#012TypeError: 'NoneType' object is not subscriptable
#12
#012During handling of the above exception, another exception occurred:
#12
#012Traceback (most recent call last):
#12 File "/usr/lib/python3.7/socketserver.py", line 650, in process_request_thread
#12 self.finish_request(request, client_address)
#12 File "/usr/lib/python3.7/socketserver.py", line 360, in finish_request
#12 self.RequestHandlerClass(request, client_address, self)
#12 File "/usr/lib/python3.7/socketserver.py", line 720, in init
#12 self.handle()
#12 File "/usr/lib/python3.7/wsgiref/simple_server.py", line 133, in handle
#12 handler.run(self.server.get_app())
#12 File "/usr/lib/python3.7/wsgiref/handlers.py", line 144, in run
#12 self.close()
#12 File "/usr/lib/python3.7/wsgiref/simple_server.py", line 35, in close
#12 self.status.split(' ',1)[0], self.bytes_sent
#012AttributeError: 'NoneType' object has no attribute 'split'


<agent_instructions>Check, if there is some possibility to handle BrokenPipeError better than this error log shows. BrokenPipeError happen, when client close connection while or before server response.</agent_instructions>

## Comments on the Issue (you are @copilot in this section)

<comments>
</comments>


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Copilot AI and others added 2 commits January 7, 2026 16:05
Co-authored-by: ondratu <6469029+ondratu@users.noreply.github.com>
Co-authored-by: ondratu <6469029+ondratu@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix broken pipe error for better output Handle BrokenPipeError gracefully when client disconnects during response Jan 7, 2026
Copilot AI requested a review from ondratu January 7, 2026 16:09
@ondratu ondratu closed this Jan 9, 2026
@ondratu ondratu deleted the copilot/fix-broken-pipe-error branch January 9, 2026 13:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

BrokenPipe ... better output

2 participants