diff options
author | Erik Johnston <erik@matrix.org> | 2018-09-20 13:44:20 +0100 |
---|---|---|
committer | Erik Johnston <erik@matrix.org> | 2018-09-20 13:44:20 +0100 |
commit | b28a7ed5030148139af6c6c03e635b068a6eae15 (patch) | |
tree | 333d1af966f4dc154d94de214a8e967ca9bfbd8f /synapse/http/server.py | |
parent | Merge pull request #3914 from matrix-org/erikj/remove_retry_cache (diff) | |
download | synapse-b28a7ed5030148139af6c6c03e635b068a6eae15.tar.xz |
Fix spurious exceptions when client closes conncetion
If a HTTP handler throws an exception while processing a request we automatically write a JSON error response. If the handler had already started writing a response twisted throws an exception. We should check for this case and simple abort the connection if there was an error after the response had started being written.
Diffstat (limited to 'synapse/http/server.py')
-rw-r--r-- | synapse/http/server.py | 49 |
1 files changed, 35 insertions, 14 deletions
diff --git a/synapse/http/server.py b/synapse/http/server.py index 2d5c23e673..b4b25cab19 100644 --- a/synapse/http/server.py +++ b/synapse/http/server.py @@ -84,10 +84,21 @@ def wrap_json_request_handler(h): logger.info( "%s SynapseError: %s - %s", request, code, e.msg ) - respond_with_json( - request, code, e.error_dict(), send_cors=True, - pretty_print=_request_user_agent_is_curl(request), - ) + + # Only respond with an error response if we haven't already started + # writing, otherwise lets just kill the connection + if request.startedWriting: + if request.transport: + try: + request.transport.abortConnection() + except Exception: + # abortConnection throws if the connection is already closed + pass + else: + respond_with_json( + request, code, e.error_dict(), send_cors=True, + pretty_print=_request_user_agent_is_curl(request), + ) except Exception: # failure.Failure() fishes the original Failure out @@ -100,16 +111,26 @@ def wrap_json_request_handler(h): request, f.getTraceback().rstrip(), ) - respond_with_json( - request, - 500, - { - "error": "Internal server error", - "errcode": Codes.UNKNOWN, - }, - send_cors=True, - pretty_print=_request_user_agent_is_curl(request), - ) + # Only respond with an error response if we haven't already started + # writing, otherwise lets just kill the connection + if request.startedWriting: + if request.transport: + try: + request.transport.abortConnection() + except Exception: + # abortConnection throws if the connection is already closed + pass + else: + respond_with_json( + request, + 500, + { + "error": "Internal server error", + "errcode": Codes.UNKNOWN, + }, + send_cors=True, + pretty_print=_request_user_agent_is_curl(request), + ) return wrap_async_request_handler(wrapped_request_handler) |