Repository: mitmproxy/mitmproxy

Issue:
Traceback when client disconnects before error message is sent.
`send_error_response` does not catch all kinds of errors:

```
127.0.0.1:52651: Traceback (most recent call last):
  File "c:\users\user\git\mitmproxy\mitmproxy\net\tcp.py", line 763, in connect
    connection.connect(self.address())
TimeoutError: [WinError 10060] Ein Verbindungsversuch ist fehlgeschlagen, da die Gegenstelle nach einer bestimmten Zeitspanne nicht richtig reagiert hat, oder die hergestellte Verbindung war fehlerhaft, da der verbundene Host nicht reagiert hat

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "c:\users\user\git\mitmproxy\mitmproxy\proxy\protocol\base.py", line 180, in connect
    self.server_conn.connect()
  File "c:\users\user\git\mitmproxy\mitmproxy\connections.py", line 206, in connect
    tcp.TCPClient.connect(self)
  File "c:\users\user\git\mitmproxy\mitmproxy\net\tcp.py", line 768, in connect
    (self.address.host, err)
mitmproxy.exceptions.TcpException: Error connecting to "baidu.com": [WinError 10060] Ein Verbindungsversuch ist fehlgeschlagen, da die Gegenstelle nach einer bestimmten Zeitspanne nicht richtig reagiert hat, oder die hergestellte Verbindung war fehlerhaft, da der verbundene Host nicht reagiert hat

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "c:\users\user\git\mitmproxy\mitmproxy\proxy\protocol\http.py", line 311, in _process_flow
    f.request.scheme
  File "c:\users\user\git\mitmproxy\mitmproxy\proxy\protocol\http.py", line 453, in establish_server_connection
    self.connect()
  File "c:\users\user\git\mitmproxy\mitmproxy\proxy\protocol\tls.py", line 397, in connect
    self.ctx.connect()
  File "c:\users\user\git\mitmproxy\mitmproxy\proxy\protocol\tls.py", line 397, in connect
    self.ctx.connect()
  File "c:\users\user\git\mitmproxy\mitmproxy\proxy\protocol\base.py", line 184, in connect
    repr(self.server_conn.address), str(e)
mitmproxy.exceptions.ProtocolException: Server connection to baidu.com:443 failed: Error connecting to "baidu.com": [WinError 10060] Ein Verbindungsversuch ist fehlgeschlagen, da die Gegenstelle nach einer bestimmten Zeitspanne nicht richtig reagiert hat, oder die hergestellte Verbindung war fehlerhaft, da der verbundene Host nicht reagiert hat

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "c:\users\user\git\mitmproxy\mitmproxy\net\tcp.py", line 188, in write
    return self.o.sendall(v)
  File "c:\python35\lib\site-packages\OpenSSL\SSL.py", line 1286, in sendall
    self._raise_ssl_error(self._ssl, result)
  File "c:\python35\lib\site-packages\OpenSSL\SSL.py", line 1166, in _raise_ssl_error
    raise SysCallError(errno, errorcode.get(errno))
OpenSSL.SSL.SysCallError: (10053, 'WSAECONNABORTED')

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "c:\users\user\git\mitmproxy\mitmproxy\proxy\protocol\http.py", line 432, in send_error_response
    self.send_response(response)
  File "c:\users\user\git\mitmproxy\mitmproxy\proxy\protocol\http.py", line 43, in send_response
    self.send_response_headers(response)
  File "c:\users\user\git\mitmproxy\mitmproxy\proxy\protocol\http1.py", line 43, in send_response_headers
    self.client_conn.wfile.write(raw)
  File "c:\users\user\git\mitmproxy\mitmproxy\net\tcp.py", line 194, in write
    raise exceptions.TcpDisconnect(str(e))
mitmproxy.exceptions.TcpDisconnect: (10053, 'WSAECONNABORTED')
```


Discussion:
My mistake, I had verbosity all the way up.
What does verbosity have to do with it?
Or do you think it is ok to show a traceback for high verbosity?
IMHO we should never ever show a traceback in the eventlog - most certainly not for `mitmproxy.exceptions.ProtocolException` errors.
I vividly remember [this line](https://github.com/mitmproxy/mitmproxy/blob/d4298cd74728982388cb8d93f93b0e463dc67b91/mitmproxy/proxy/protocol/http.py#L434) for some very ugly socket-related debugging on Windows, where it was incredibly useful. You are right though, we should just log the error message here and not the full traceback.

Resolving patch:
diff --git a/mitmproxy/proxy/protocol/http.py b/mitmproxy/proxy/protocol/http.py
--- a/mitmproxy/proxy/protocol/http.py
+++ b/mitmproxy/proxy/protocol/http.py
@@ -1,6 +1,5 @@
 import h2.exceptions
 import time
-import traceback
 import enum
 
 from mitmproxy import connections  # noqa
@@ -431,7 +430,7 @@ def send_error_response(self, code, message, headers=None) -> None:
             response = http.make_error_response(code, message, headers)
             self.send_response(response)
         except (exceptions.NetlibException, h2.exceptions.H2Error, exceptions.Http2ProtocolException):
-            self.log(traceback.format_exc(), "debug")
+            self.log("Failed to send error response to client: {}".format(message), "debug")
 
     def change_upstream_proxy_server(self, address) -> None:
         # Make set_upstream_proxy_server always available,


Test patch: