prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  ServerException instead of ProxyServerError
  ##### Steps to reproduce the problem:
  
  ```
  >>> from libmproxy.proxy.server import ProxyServer
  >>> from libmproxy.proxy.config import ProxyConfig
  >>> ProxyServer(ProxyConfig(port=80))
  (...)
  ServerException: Error starting proxy server: error(13, 'Permission denied')
  ```
  ##### What is the expected behavior?
  
  According to the documentation:
  
  ```
  >>> ProxyServer?                       
  Type:            type
  String form:     <class 'libmproxy.proxy.server.ProxyServer'>
  File:            /usr/lib/python2.7/dist-packages/libmproxy/proxy/server.py
  Init definition: ProxyServer(self, config)
  Docstring:       <no docstring>
  Init docstring:  Raises ProxyServerError if there's a startup problem.
  ```
  
  the expected behavior is 
  
  ```
  >>> ProxyServer(ProxyConfig(port=80))
  (...)
  ProxyServerError: Error starting proxy server: error(13, 'Permission denied')
  ```
  ##### What went wrong?
  
  Maybe the documentation is wrong?
  ##### Any other comments?
  
  Nope.
  
  ---
  
  Mitmproxy Version: 0.15-2
  Operating System: Debian Sid.
  
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `mitmproxy/proxy/server.py`
  Content:
  ```
  1 from __future__ import (absolute_import, print_function, division)
  2 
  3 import traceback
  4 import sys
  5 import socket
  6 import six
  7 
  8 from netlib import tcp
  9 from netlib.exceptions import TcpException
  10 from netlib.http.http1 import assemble_response
  11 from ..exceptions import ProtocolException, ServerException, ClientHandshakeException, Kill
  12 from ..models import ClientConnection, make_error_response
  13 from .modes import HttpUpstreamProxy, HttpProxy, ReverseProxy, TransparentProxy, Socks5Proxy
  14 from .root_context import RootContext, Log
  15 
  16 
  17 class DummyServer:
  18     bound = False
  19 
  20     def __init__(self, config):
  21         self.config = config
  22 
  23     def set_channel(self, channel):
  24         pass
  25 
  26     def serve_forever(self):
  27         pass
  28 
  29     def shutdown(self):
  30         pass
  31 
  32 
  33 class ProxyServer(tcp.TCPServer):
  34     allow_reuse_address = True
  35     bound = True
  36 
  37     def __init__(self, config):
  38         """
  39             Raises ProxyServerError if there's a startup problem.
  40         """
  41         self.config = config
  42         try:
  43             super(ProxyServer, self).__init__((config.host, config.port))
  44         except socket.error as e:
  45             six.reraise(
  46                 ServerException,
  47                 ServerException('Error starting proxy server: ' + repr(e)),
  48                 sys.exc_info()[2]
  49             )
  50         self.channel = None
  51 
  52     def set_channel(self, channel):
  53         self.channel = channel
  54 
  55     def handle_client_connection(self, conn, client_address):
  56         h = ConnectionHandler(
  57             conn,
  58             client_address,
  59             self.config,
  60             self.channel
  61         )
  62         h.handle()
  63 
  64 
  65 class ConnectionHandler(object):
  66 
  67     def __init__(self, client_conn, client_address, config, channel):
  68         self.config = config
  69         """@type: mitmproxy.proxy.config.ProxyConfig"""
  70         self.client_conn = ClientConnection(
  71             client_conn,
  72             client_address,
  73             None)
  74         """@type: mitmproxy.proxy.connection.ClientConnection"""
  75         self.channel = channel
  76         """@type: mitmproxy.controller.Channel"""
  77 
  78     def _create_root_layer(self):
  79         root_context = RootContext(
  80             self.client_conn,
  81             self.config,
  82             self.channel
  83         )
  84 
  85         mode = self.config.mode
  86         if mode == "upstream":
  87             return HttpUpstreamProxy(
  88                 root_context,
  89                 self.config.upstream_server.address
  90             )
  91         elif mode == "transparent":
  92             return TransparentProxy(root_context)
  93         elif mode == "reverse":
  94             server_tls = self.config.upstream_server.scheme == "https"
  95             return ReverseProxy(
  96                 root_context,
  97                 self.config.upstream_server.address,
  98                 server_tls
  99             )
  100         elif mode == "socks5":
  101             return Socks5Proxy(root_context)
  102         elif mode == "regular":
  103             return HttpProxy(root_context)
  104         elif callable(mode):  # pragma: no cover
  105             return mode(root_context)
  106         else:  # pragma: no cover
  107             raise ValueError("Unknown proxy mode: %s" % mode)
  108 
  109     def handle(self):
  110         self.log("clientconnect", "info")
  111 
  112         root_layer = self._create_root_layer()
  113 
  114         try:
  115             root_layer = self.channel.ask("clientconnect", root_layer)
  116             root_layer()
  117         except Kill:
  118             self.log("Connection killed", "info")
  119         except ProtocolException as e:
  120 
  121             if isinstance(e, ClientHandshakeException):
  122                 self.log(
  123                     "Client Handshake failed. "
  124                     "The client may not trust the proxy's certificate for {}.".format(e.server),
  125                     "error"
  126                 )
  127                 self.log(repr(e), "debug")
  128             else:
  129                 self.log(repr(e), "info")
  130 
  131                 self.log(traceback.format_exc(), "debug")
  132             # If an error propagates to the topmost level,
  133             # we send an HTTP error response, which is both
  134             # understandable by HTTP clients and humans.
  135             try:
  136                 error_response = make_error_response(502, repr(e))
  137                 self.client_conn.send(assemble_response(error_response))
  138             except TcpException:
  139                 pass
  140         except Exception:
  141             self.log(traceback.format_exc(), "error")
  142             print(traceback.format_exc(), file=sys.stderr)
  143             print("mitmproxy has crashed!", file=sys.stderr)
  144             print("Please lodge a bug report at: https://github.com/mitmproxy/mitmproxy", file=sys.stderr)
  145 
  146         self.log("clientdisconnect", "info")
  147         self.channel.tell("clientdisconnect", root_layer)
  148         self.client_conn.finish()
  149 
  150     def log(self, msg, level):
  151         msg = "{}: {}".format(repr(self.client_conn.address), msg)
  152         self.channel.tell("log", Log(msg, level))
  153
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/mitmproxy/proxy/server.py b/mitmproxy/proxy/server.py
  --- a/mitmproxy/proxy/server.py
  +++ b/mitmproxy/proxy/server.py
  @@ -36,7 +36,7 @@
   
       def __init__(self, config):
           """
  -            Raises ProxyServerError if there's a startup problem.
  +            Raises ServerException if there's a startup problem.
           """
           self.config = config
           try:
  
verification_info: {"golden_diff": "diff --git a/mitmproxy/proxy/server.py b/mitmproxy/proxy/server.py\n--- a/mitmproxy/proxy/server.py\n+++ b/mitmproxy/proxy/server.py\n@@ -36,7 +36,7 @@\n \n     def __init__(self, config):\n         \"\"\"\n-            Raises ProxyServerError if there's a startup problem.\n+            Raises ServerException if there's a startup problem.\n         \"\"\"\n         self.config = config\n         try:\n", "issue": "ServerException instead of ProxyServerError\n##### Steps to reproduce the problem:\n\n```\n>>> from libmproxy.proxy.server import ProxyServer\n>>> from libmproxy.proxy.config import ProxyConfig\n>>> ProxyServer(ProxyConfig(port=80))\n(...)\nServerException: Error starting proxy server: error(13, 'Permission denied')\n```\n##### What is the expected behavior?\n\nAccording to the documentation:\n\n```\n>>> ProxyServer?                       \nType:            type\nString form:     <class 'libmproxy.proxy.server.ProxyServer'>\nFile:            /usr/lib/python2.7/dist-packages/libmproxy/proxy/server.py\nInit definition: ProxyServer(self, config)\nDocstring:       <no docstring>\nInit docstring:  Raises ProxyServerError if there's a startup problem.\n```\n\nthe expected behavior is \n\n```\n>>> ProxyServer(ProxyConfig(port=80))\n(...)\nProxyServerError: Error starting proxy server: error(13, 'Permission denied')\n```\n##### What went wrong?\n\nMaybe the documentation is wrong?\n##### Any other comments?\n\nNope.\n\n---\n\nMitmproxy Version: 0.15-2\nOperating System: Debian Sid.\n\n", "before_files": [{"content": "from __future__ import (absolute_import, print_function, division)\n\nimport traceback\nimport sys\nimport socket\nimport six\n\nfrom netlib import tcp\nfrom netlib.exceptions import TcpException\nfrom netlib.http.http1 import assemble_response\nfrom ..exceptions import ProtocolException, ServerException, ClientHandshakeException, Kill\nfrom ..models import ClientConnection, make_error_response\nfrom .modes import HttpUpstreamProxy, HttpProxy, ReverseProxy, TransparentProxy, Socks5Proxy\nfrom .root_context import RootContext, Log\n\n\nclass DummyServer:\n    bound = False\n\n    def __init__(self, config):\n        self.config = config\n\n    def set_channel(self, channel):\n        pass\n\n    def serve_forever(self):\n        pass\n\n    def shutdown(self):\n        pass\n\n\nclass ProxyServer(tcp.TCPServer):\n    allow_reuse_address = True\n    bound = True\n\n    def __init__(self, config):\n        \"\"\"\n            Raises ProxyServerError if there's a startup problem.\n        \"\"\"\n        self.config = config\n        try:\n            super(ProxyServer, self).__init__((config.host, config.port))\n        except socket.error as e:\n            six.reraise(\n                ServerException,\n                ServerException('Error starting proxy server: ' + repr(e)),\n                sys.exc_info()[2]\n            )\n        self.channel = None\n\n    def set_channel(self, channel):\n        self.channel = channel\n\n    def handle_client_connection(self, conn, client_address):\n        h = ConnectionHandler(\n            conn,\n            client_address,\n            self.config,\n            self.channel\n        )\n        h.handle()\n\n\nclass ConnectionHandler(object):\n\n    def __init__(self, client_conn, client_address, config, channel):\n        self.config = config\n        \"\"\"@type: mitmproxy.proxy.config.ProxyConfig\"\"\"\n        self.client_conn = ClientConnection(\n            client_conn,\n            client_address,\n            None)\n        \"\"\"@type: mitmproxy.proxy.connection.ClientConnection\"\"\"\n        self.channel = channel\n        \"\"\"@type: mitmproxy.controller.Channel\"\"\"\n\n    def _create_root_layer(self):\n        root_context = RootContext(\n            self.client_conn,\n            self.config,\n            self.channel\n        )\n\n        mode = self.config.mode\n        if mode == \"upstream\":\n            return HttpUpstreamProxy(\n                root_context,\n                self.config.upstream_server.address\n            )\n        elif mode == \"transparent\":\n            return TransparentProxy(root_context)\n        elif mode == \"reverse\":\n            server_tls = self.config.upstream_server.scheme == \"https\"\n            return ReverseProxy(\n                root_context,\n                self.config.upstream_server.address,\n                server_tls\n            )\n        elif mode == \"socks5\":\n            return Socks5Proxy(root_context)\n        elif mode == \"regular\":\n            return HttpProxy(root_context)\n        elif callable(mode):  # pragma: no cover\n            return mode(root_context)\n        else:  # pragma: no cover\n            raise ValueError(\"Unknown proxy mode: %s\" % mode)\n\n    def handle(self):\n        self.log(\"clientconnect\", \"info\")\n\n        root_layer = self._create_root_layer()\n\n        try:\n            root_layer = self.channel.ask(\"clientconnect\", root_layer)\n            root_layer()\n        except Kill:\n            self.log(\"Connection killed\", \"info\")\n        except ProtocolException as e:\n\n            if isinstance(e, ClientHandshakeException):\n                self.log(\n                    \"Client Handshake failed. \"\n                    \"The client may not trust the proxy's certificate for {}.\".format(e.server),\n                    \"error\"\n                )\n                self.log(repr(e), \"debug\")\n            else:\n                self.log(repr(e), \"info\")\n\n                self.log(traceback.format_exc(), \"debug\")\n            # If an error propagates to the topmost level,\n            # we send an HTTP error response, which is both\n            # understandable by HTTP clients and humans.\n            try:\n                error_response = make_error_response(502, repr(e))\n                self.client_conn.send(assemble_response(error_response))\n            except TcpException:\n                pass\n        except Exception:\n            self.log(traceback.format_exc(), \"error\")\n            print(traceback.format_exc(), file=sys.stderr)\n            print(\"mitmproxy has crashed!\", file=sys.stderr)\n            print(\"Please lodge a bug report at: https://github.com/mitmproxy/mitmproxy\", file=sys.stderr)\n\n        self.log(\"clientdisconnect\", \"info\")\n        self.channel.tell(\"clientdisconnect\", root_layer)\n        self.client_conn.finish()\n\n    def log(self, msg, level):\n        msg = \"{}: {}\".format(repr(self.client_conn.address), msg)\n        self.channel.tell(\"log\", Log(msg, level))\n", "path": "mitmproxy/proxy/server.py"}], "after_files": [{"content": "from __future__ import (absolute_import, print_function, division)\n\nimport traceback\nimport sys\nimport socket\nimport six\n\nfrom netlib import tcp\nfrom netlib.exceptions import TcpException\nfrom netlib.http.http1 import assemble_response\nfrom ..exceptions import ProtocolException, ServerException, ClientHandshakeException, Kill\nfrom ..models import ClientConnection, make_error_response\nfrom .modes import HttpUpstreamProxy, HttpProxy, ReverseProxy, TransparentProxy, Socks5Proxy\nfrom .root_context import RootContext, Log\n\n\nclass DummyServer:\n    bound = False\n\n    def __init__(self, config):\n        self.config = config\n\n    def set_channel(self, channel):\n        pass\n\n    def serve_forever(self):\n        pass\n\n    def shutdown(self):\n        pass\n\n\nclass ProxyServer(tcp.TCPServer):\n    allow_reuse_address = True\n    bound = True\n\n    def __init__(self, config):\n        \"\"\"\n            Raises ServerException if there's a startup problem.\n        \"\"\"\n        self.config = config\n        try:\n            super(ProxyServer, self).__init__((config.host, config.port))\n        except socket.error as e:\n            six.reraise(\n                ServerException,\n                ServerException('Error starting proxy server: ' + repr(e)),\n                sys.exc_info()[2]\n            )\n        self.channel = None\n\n    def set_channel(self, channel):\n        self.channel = channel\n\n    def handle_client_connection(self, conn, client_address):\n        h = ConnectionHandler(\n            conn,\n            client_address,\n            self.config,\n            self.channel\n        )\n        h.handle()\n\n\nclass ConnectionHandler(object):\n\n    def __init__(self, client_conn, client_address, config, channel):\n        self.config = config\n        \"\"\"@type: mitmproxy.proxy.config.ProxyConfig\"\"\"\n        self.client_conn = ClientConnection(\n            client_conn,\n            client_address,\n            None)\n        \"\"\"@type: mitmproxy.proxy.connection.ClientConnection\"\"\"\n        self.channel = channel\n        \"\"\"@type: mitmproxy.controller.Channel\"\"\"\n\n    def _create_root_layer(self):\n        root_context = RootContext(\n            self.client_conn,\n            self.config,\n            self.channel\n        )\n\n        mode = self.config.mode\n        if mode == \"upstream\":\n            return HttpUpstreamProxy(\n                root_context,\n                self.config.upstream_server.address\n            )\n        elif mode == \"transparent\":\n            return TransparentProxy(root_context)\n        elif mode == \"reverse\":\n            server_tls = self.config.upstream_server.scheme == \"https\"\n            return ReverseProxy(\n                root_context,\n                self.config.upstream_server.address,\n                server_tls\n            )\n        elif mode == \"socks5\":\n            return Socks5Proxy(root_context)\n        elif mode == \"regular\":\n            return HttpProxy(root_context)\n        elif callable(mode):  # pragma: no cover\n            return mode(root_context)\n        else:  # pragma: no cover\n            raise ValueError(\"Unknown proxy mode: %s\" % mode)\n\n    def handle(self):\n        self.log(\"clientconnect\", \"info\")\n\n        root_layer = self._create_root_layer()\n\n        try:\n            root_layer = self.channel.ask(\"clientconnect\", root_layer)\n            root_layer()\n        except Kill:\n            self.log(\"Connection killed\", \"info\")\n        except ProtocolException as e:\n\n            if isinstance(e, ClientHandshakeException):\n                self.log(\n                    \"Client Handshake failed. \"\n                    \"The client may not trust the proxy's certificate for {}.\".format(e.server),\n                    \"error\"\n                )\n                self.log(repr(e), \"debug\")\n            else:\n                self.log(repr(e), \"info\")\n\n                self.log(traceback.format_exc(), \"debug\")\n            # If an error propagates to the topmost level,\n            # we send an HTTP error response, which is both\n            # understandable by HTTP clients and humans.\n            try:\n                error_response = make_error_response(502, repr(e))\n                self.client_conn.send(assemble_response(error_response))\n            except TcpException:\n                pass\n        except Exception:\n            self.log(traceback.format_exc(), \"error\")\n            print(traceback.format_exc(), file=sys.stderr)\n            print(\"mitmproxy has crashed!\", file=sys.stderr)\n            print(\"Please lodge a bug report at: https://github.com/mitmproxy/mitmproxy\", file=sys.stderr)\n\n        self.log(\"clientdisconnect\", \"info\")\n        self.channel.tell(\"clientdisconnect\", root_layer)\n        self.client_conn.finish()\n\n    def log(self, msg, level):\n        msg = \"{}: {}\".format(repr(self.client_conn.address), msg)\n        self.channel.tell(\"log\", Log(msg, level))\n", "path": "mitmproxy/proxy/server.py"}]}