We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Denying WebSocket connection in WebSocketEndpoint.on_connect leads to Exception
### Discussed in https://github.com/encode/starlette/discussions/1555

<div type='discussions-op-text'>

<sup>Originally posted by **dingensundso** March 27, 2022</sup>
I created a WebSocketEndpoint class in which I want to deny the connection in certain conditions.
When the WebSocket is closed in on_connect I receive the following exception:

```
  File "starlette/endpoints.py", line 83, in dispatch
    close_code = int(message.get("code", status.WS_1000_NORMAL_CLOSURE))
TypeError: int() argument must be a string, a bytes-like object or a real number, not 'NoneType'
```
So code is None when the server denies the connection instead of non-existant.

https://github.com/encode/starlette/blob/e086fc2da361767b532cf690e5203619bbae98aa/starlette/endpoints.py#L72-L87

Changing line 83 to the following should fix the issue:
```python
close_code = int(message.get("code") or status.WS_1000_NORMAL_CLOSURE)               
````
</div>

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `starlette/endpoints.py`
Content:
```
1 import asyncio
2 import json
3 import typing
4 
5 from starlette import status
6 from starlette.concurrency import run_in_threadpool
7 from starlette.exceptions import HTTPException
8 from starlette.requests import Request
9 from starlette.responses import PlainTextResponse, Response
10 from starlette.types import Message, Receive, Scope, Send
11 from starlette.websockets import WebSocket
12 
13 
14 class HTTPEndpoint:
15     def __init__(self, scope: Scope, receive: Receive, send: Send) -> None:
16         assert scope["type"] == "http"
17         self.scope = scope
18         self.receive = receive
19         self.send = send
20         self._allowed_methods = [
21             method
22             for method in ("GET", "HEAD", "POST", "PUT", "PATCH", "DELETE", "OPTIONS")
23             if getattr(self, method.lower(), None) is not None
24         ]
25 
26     def __await__(self) -> typing.Generator:
27         return self.dispatch().__await__()
28 
29     async def dispatch(self) -> None:
30         request = Request(self.scope, receive=self.receive)
31         handler_name = (
32             "get"
33             if request.method == "HEAD" and not hasattr(self, "head")
34             else request.method.lower()
35         )
36 
37         handler: typing.Callable[[Request], typing.Any] = getattr(
38             self, handler_name, self.method_not_allowed
39         )
40         is_async = asyncio.iscoroutinefunction(handler)
41         if is_async:
42             response = await handler(request)
43         else:
44             response = await run_in_threadpool(handler, request)
45         await response(self.scope, self.receive, self.send)
46 
47     async def method_not_allowed(self, request: Request) -> Response:
48         # If we're running inside a starlette application then raise an
49         # exception, so that the configurable exception handler can deal with
50         # returning the response. For plain ASGI apps, just return the response.
51         headers = {"Allow": ", ".join(self._allowed_methods)}
52         if "app" in self.scope:
53             raise HTTPException(status_code=405, headers=headers)
54         return PlainTextResponse("Method Not Allowed", status_code=405, headers=headers)
55 
56 
57 class WebSocketEndpoint:
58 
59     encoding: typing.Optional[str] = None  # May be "text", "bytes", or "json".
60 
61     def __init__(self, scope: Scope, receive: Receive, send: Send) -> None:
62         assert scope["type"] == "websocket"
63         self.scope = scope
64         self.receive = receive
65         self.send = send
66 
67     def __await__(self) -> typing.Generator:
68         return self.dispatch().__await__()
69 
70     async def dispatch(self) -> None:
71         websocket = WebSocket(self.scope, receive=self.receive, send=self.send)
72         await self.on_connect(websocket)
73 
74         close_code = status.WS_1000_NORMAL_CLOSURE
75 
76         try:
77             while True:
78                 message = await websocket.receive()
79                 if message["type"] == "websocket.receive":
80                     data = await self.decode(websocket, message)
81                     await self.on_receive(websocket, data)
82                 elif message["type"] == "websocket.disconnect":
83                     close_code = int(message.get("code", status.WS_1000_NORMAL_CLOSURE))
84                     break
85         except Exception as exc:
86             close_code = status.WS_1011_INTERNAL_ERROR
87             raise exc
88         finally:
89             await self.on_disconnect(websocket, close_code)
90 
91     async def decode(self, websocket: WebSocket, message: Message) -> typing.Any:
92 
93         if self.encoding == "text":
94             if "text" not in message:
95                 await websocket.close(code=status.WS_1003_UNSUPPORTED_DATA)
96                 raise RuntimeError("Expected text websocket messages, but got bytes")
97             return message["text"]
98 
99         elif self.encoding == "bytes":
100             if "bytes" not in message:
101                 await websocket.close(code=status.WS_1003_UNSUPPORTED_DATA)
102                 raise RuntimeError("Expected bytes websocket messages, but got text")
103             return message["bytes"]
104 
105         elif self.encoding == "json":
106             if message.get("text") is not None:
107                 text = message["text"]
108             else:
109                 text = message["bytes"].decode("utf-8")
110 
111             try:
112                 return json.loads(text)
113             except json.decoder.JSONDecodeError:
114                 await websocket.close(code=status.WS_1003_UNSUPPORTED_DATA)
115                 raise RuntimeError("Malformed JSON data received.")
116 
117         assert (
118             self.encoding is None
119         ), f"Unsupported 'encoding' attribute {self.encoding}"
120         return message["text"] if message.get("text") else message["bytes"]
121 
122     async def on_connect(self, websocket: WebSocket) -> None:
123         """Override to handle an incoming websocket connection"""
124         await websocket.accept()
125 
126     async def on_receive(self, websocket: WebSocket, data: typing.Any) -> None:
127         """Override to handle an incoming websocket message"""
128 
129     async def on_disconnect(self, websocket: WebSocket, close_code: int) -> None:
130         """Override to handle a disconnecting websocket"""
131
```
--- 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()

```

diff --git a/starlette/endpoints.py b/starlette/endpoints.py
--- a/starlette/endpoints.py
+++ b/starlette/endpoints.py
@@ -80,7 +80,9 @@
                     data = await self.decode(websocket, message)
                     await self.on_receive(websocket, data)
                 elif message["type"] == "websocket.disconnect":
-                    close_code = int(message.get("code", status.WS_1000_NORMAL_CLOSURE))
+                    close_code = int(
+                        message.get("code") or status.WS_1000_NORMAL_CLOSURE
+                    )
                     break
         except Exception as exc:
             close_code = status.WS_1011_INTERNAL_ERROR

{"golden_diff": "diff --git a/starlette/endpoints.py b/starlette/endpoints.py\n--- a/starlette/endpoints.py\n+++ b/starlette/endpoints.py\n@@ -80,7 +80,9 @@\n                     data = await self.decode(websocket, message)\n                     await self.on_receive(websocket, data)\n                 elif message[\"type\"] == \"websocket.disconnect\":\n-                    close_code = int(message.get(\"code\", status.WS_1000_NORMAL_CLOSURE))\n+                    close_code = int(\n+                        message.get(\"code\") or status.WS_1000_NORMAL_CLOSURE\n+                    )\n                     break\n         except Exception as exc:\n             close_code = status.WS_1011_INTERNAL_ERROR\n", "issue": "Denying WebSocket connection in WebSocketEndpoint.on_connect leads to Exception\n### Discussed in https://github.com/encode/starlette/discussions/1555\r\n\r\n<div type='discussions-op-text'>\r\n\r\n<sup>Originally posted by **dingensundso** March 27, 2022</sup>\r\nI created a WebSocketEndpoint class in which I want to deny the connection in certain conditions.\r\nWhen the WebSocket is closed in on_connect I receive the following exception:\r\n\r\n```\r\n  File \"starlette/endpoints.py\", line 83, in dispatch\r\n    close_code = int(message.get(\"code\", status.WS_1000_NORMAL_CLOSURE))\r\nTypeError: int() argument must be a string, a bytes-like object or a real number, not 'NoneType'\r\n```\r\nSo code is None when the server denies the connection instead of non-existant.\r\n\r\nhttps://github.com/encode/starlette/blob/e086fc2da361767b532cf690e5203619bbae98aa/starlette/endpoints.py#L72-L87\r\n\r\nChanging line 83 to the following should fix the issue:\r\n```python\r\nclose_code = int(message.get(\"code\") or status.WS_1000_NORMAL_CLOSURE)               \r\n````\r\n</div>\n", "before_files": [{"content": "import asyncio\nimport json\nimport typing\n\nfrom starlette import status\nfrom starlette.concurrency import run_in_threadpool\nfrom starlette.exceptions import HTTPException\nfrom starlette.requests import Request\nfrom starlette.responses import PlainTextResponse, Response\nfrom starlette.types import Message, Receive, Scope, Send\nfrom starlette.websockets import WebSocket\n\n\nclass HTTPEndpoint:\n    def __init__(self, scope: Scope, receive: Receive, send: Send) -> None:\n        assert scope[\"type\"] == \"http\"\n        self.scope = scope\n        self.receive = receive\n        self.send = send\n        self._allowed_methods = [\n            method\n            for method in (\"GET\", \"HEAD\", \"POST\", \"PUT\", \"PATCH\", \"DELETE\", \"OPTIONS\")\n            if getattr(self, method.lower(), None) is not None\n        ]\n\n    def __await__(self) -> typing.Generator:\n        return self.dispatch().__await__()\n\n    async def dispatch(self) -> None:\n        request = Request(self.scope, receive=self.receive)\n        handler_name = (\n            \"get\"\n            if request.method == \"HEAD\" and not hasattr(self, \"head\")\n            else request.method.lower()\n        )\n\n        handler: typing.Callable[[Request], typing.Any] = getattr(\n            self, handler_name, self.method_not_allowed\n        )\n        is_async = asyncio.iscoroutinefunction(handler)\n        if is_async:\n            response = await handler(request)\n        else:\n            response = await run_in_threadpool(handler, request)\n        await response(self.scope, self.receive, self.send)\n\n    async def method_not_allowed(self, request: Request) -> Response:\n        # If we're running inside a starlette application then raise an\n        # exception, so that the configurable exception handler can deal with\n        # returning the response. For plain ASGI apps, just return the response.\n        headers = {\"Allow\": \", \".join(self._allowed_methods)}\n        if \"app\" in self.scope:\n            raise HTTPException(status_code=405, headers=headers)\n        return PlainTextResponse(\"Method Not Allowed\", status_code=405, headers=headers)\n\n\nclass WebSocketEndpoint:\n\n    encoding: typing.Optional[str] = None  # May be \"text\", \"bytes\", or \"json\".\n\n    def __init__(self, scope: Scope, receive: Receive, send: Send) -> None:\n        assert scope[\"type\"] == \"websocket\"\n        self.scope = scope\n        self.receive = receive\n        self.send = send\n\n    def __await__(self) -> typing.Generator:\n        return self.dispatch().__await__()\n\n    async def dispatch(self) -> None:\n        websocket = WebSocket(self.scope, receive=self.receive, send=self.send)\n        await self.on_connect(websocket)\n\n        close_code = status.WS_1000_NORMAL_CLOSURE\n\n        try:\n            while True:\n                message = await websocket.receive()\n                if message[\"type\"] == \"websocket.receive\":\n                    data = await self.decode(websocket, message)\n                    await self.on_receive(websocket, data)\n                elif message[\"type\"] == \"websocket.disconnect\":\n                    close_code = int(message.get(\"code\", status.WS_1000_NORMAL_CLOSURE))\n                    break\n        except Exception as exc:\n            close_code = status.WS_1011_INTERNAL_ERROR\n            raise exc\n        finally:\n            await self.on_disconnect(websocket, close_code)\n\n    async def decode(self, websocket: WebSocket, message: Message) -> typing.Any:\n\n        if self.encoding == \"text\":\n            if \"text\" not in message:\n                await websocket.close(code=status.WS_1003_UNSUPPORTED_DATA)\n                raise RuntimeError(\"Expected text websocket messages, but got bytes\")\n            return message[\"text\"]\n\n        elif self.encoding == \"bytes\":\n            if \"bytes\" not in message:\n                await websocket.close(code=status.WS_1003_UNSUPPORTED_DATA)\n                raise RuntimeError(\"Expected bytes websocket messages, but got text\")\n            return message[\"bytes\"]\n\n        elif self.encoding == \"json\":\n            if message.get(\"text\") is not None:\n                text = message[\"text\"]\n            else:\n                text = message[\"bytes\"].decode(\"utf-8\")\n\n            try:\n                return json.loads(text)\n            except json.decoder.JSONDecodeError:\n                await websocket.close(code=status.WS_1003_UNSUPPORTED_DATA)\n                raise RuntimeError(\"Malformed JSON data received.\")\n\n        assert (\n            self.encoding is None\n        ), f\"Unsupported 'encoding' attribute {self.encoding}\"\n        return message[\"text\"] if message.get(\"text\") else message[\"bytes\"]\n\n    async def on_connect(self, websocket: WebSocket) -> None:\n        \"\"\"Override to handle an incoming websocket connection\"\"\"\n        await websocket.accept()\n\n    async def on_receive(self, websocket: WebSocket, data: typing.Any) -> None:\n        \"\"\"Override to handle an incoming websocket message\"\"\"\n\n    async def on_disconnect(self, websocket: WebSocket, close_code: int) -> None:\n        \"\"\"Override to handle a disconnecting websocket\"\"\"\n", "path": "starlette/endpoints.py"}], "after_files": [{"content": "import asyncio\nimport json\nimport typing\n\nfrom starlette import status\nfrom starlette.concurrency import run_in_threadpool\nfrom starlette.exceptions import HTTPException\nfrom starlette.requests import Request\nfrom starlette.responses import PlainTextResponse, Response\nfrom starlette.types import Message, Receive, Scope, Send\nfrom starlette.websockets import WebSocket\n\n\nclass HTTPEndpoint:\n    def __init__(self, scope: Scope, receive: Receive, send: Send) -> None:\n        assert scope[\"type\"] == \"http\"\n        self.scope = scope\n        self.receive = receive\n        self.send = send\n        self._allowed_methods = [\n            method\n            for method in (\"GET\", \"HEAD\", \"POST\", \"PUT\", \"PATCH\", \"DELETE\", \"OPTIONS\")\n            if getattr(self, method.lower(), None) is not None\n        ]\n\n    def __await__(self) -> typing.Generator:\n        return self.dispatch().__await__()\n\n    async def dispatch(self) -> None:\n        request = Request(self.scope, receive=self.receive)\n        handler_name = (\n            \"get\"\n            if request.method == \"HEAD\" and not hasattr(self, \"head\")\n            else request.method.lower()\n        )\n\n        handler: typing.Callable[[Request], typing.Any] = getattr(\n            self, handler_name, self.method_not_allowed\n        )\n        is_async = asyncio.iscoroutinefunction(handler)\n        if is_async:\n            response = await handler(request)\n        else:\n            response = await run_in_threadpool(handler, request)\n        await response(self.scope, self.receive, self.send)\n\n    async def method_not_allowed(self, request: Request) -> Response:\n        # If we're running inside a starlette application then raise an\n        # exception, so that the configurable exception handler can deal with\n        # returning the response. For plain ASGI apps, just return the response.\n        headers = {\"Allow\": \", \".join(self._allowed_methods)}\n        if \"app\" in self.scope:\n            raise HTTPException(status_code=405, headers=headers)\n        return PlainTextResponse(\"Method Not Allowed\", status_code=405, headers=headers)\n\n\nclass WebSocketEndpoint:\n\n    encoding: typing.Optional[str] = None  # May be \"text\", \"bytes\", or \"json\".\n\n    def __init__(self, scope: Scope, receive: Receive, send: Send) -> None:\n        assert scope[\"type\"] == \"websocket\"\n        self.scope = scope\n        self.receive = receive\n        self.send = send\n\n    def __await__(self) -> typing.Generator:\n        return self.dispatch().__await__()\n\n    async def dispatch(self) -> None:\n        websocket = WebSocket(self.scope, receive=self.receive, send=self.send)\n        await self.on_connect(websocket)\n\n        close_code = status.WS_1000_NORMAL_CLOSURE\n\n        try:\n            while True:\n                message = await websocket.receive()\n                if message[\"type\"] == \"websocket.receive\":\n                    data = await self.decode(websocket, message)\n                    await self.on_receive(websocket, data)\n                elif message[\"type\"] == \"websocket.disconnect\":\n                    close_code = int(\n                        message.get(\"code\") or status.WS_1000_NORMAL_CLOSURE\n                    )\n                    break\n        except Exception as exc:\n            close_code = status.WS_1011_INTERNAL_ERROR\n            raise exc\n        finally:\n            await self.on_disconnect(websocket, close_code)\n\n    async def decode(self, websocket: WebSocket, message: Message) -> typing.Any:\n\n        if self.encoding == \"text\":\n            if \"text\" not in message:\n                await websocket.close(code=status.WS_1003_UNSUPPORTED_DATA)\n                raise RuntimeError(\"Expected text websocket messages, but got bytes\")\n            return message[\"text\"]\n\n        elif self.encoding == \"bytes\":\n            if \"bytes\" not in message:\n                await websocket.close(code=status.WS_1003_UNSUPPORTED_DATA)\n                raise RuntimeError(\"Expected bytes websocket messages, but got text\")\n            return message[\"bytes\"]\n\n        elif self.encoding == \"json\":\n            if message.get(\"text\") is not None:\n                text = message[\"text\"]\n            else:\n                text = message[\"bytes\"].decode(\"utf-8\")\n\n            try:\n                return json.loads(text)\n            except json.decoder.JSONDecodeError:\n                await websocket.close(code=status.WS_1003_UNSUPPORTED_DATA)\n                raise RuntimeError(\"Malformed JSON data received.\")\n\n        assert (\n            self.encoding is None\n        ), f\"Unsupported 'encoding' attribute {self.encoding}\"\n        return message[\"text\"] if message.get(\"text\") else message[\"bytes\"]\n\n    async def on_connect(self, websocket: WebSocket) -> None:\n        \"\"\"Override to handle an incoming websocket connection\"\"\"\n        await websocket.accept()\n\n    async def on_receive(self, websocket: WebSocket, data: typing.Any) -> None:\n        \"\"\"Override to handle an incoming websocket message\"\"\"\n\n    async def on_disconnect(self, websocket: WebSocket, close_code: int) -> None:\n        \"\"\"Override to handle a disconnecting websocket\"\"\"\n", "path": "starlette/endpoints.py"}]}