Encountering “Error: Exception in ASGI application” for WebSocket server with FastAPI

Hi I am trying to create a simple WebSocket server and client with python and FastAPI.
When I run the server.py and it receives a message from client.py, the server will throw up the follow stack trace and the websocket connection closes, before the loop iterates to open a new websocket server. What is the cause of the error and why does the websocket connection closes?

I sometimes encounter other starlette.websockets.WebSocketDisconnect error messages with code 1006 and 1012 as well.

Appreciate the help, thank you!

Stack Trace shows the console output after running server and client scripts

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>INFO: Started server process [17852]
INFO: Waiting for application startup.
INFO: Application startup complete.
INFO: Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)
INFO: ('127.0.0.1', 64479) - "WebSocket /ws" [accepted]
INFO: connection open
server parsed message
broadcasted message to all connected clients
ERROR: Exception in ASGI application
Traceback (most recent call last):
File "C:UserstankaAppDataRoamingPythonPython310site-packagesuvicornprotocolswebsocketswebsockets_impl.py", line 244, in run_asgi
result = await self.app(self.scope, self.asgi_receive, self.asgi_send) # type: ignore[func-returns-value]
File "C:UserstankaAppDataRoamingPythonPython310site-packagesuvicornmiddlewareproxy_headers.py", line 70, in __call__
return await self.app(scope, receive, send)
File "C:UserstankaAppDataRoamingPythonPython310site-packagesfastapiapplications.py", line 1054, in __call__
await super().__call__(scope, receive, send)
File "C:UserstankaAppDataRoamingPythonPython310site-packagesstarletteapplications.py", line 123, in __call__
await self.middleware_stack(scope, receive, send)
File "C:UserstankaAppDataRoamingPythonPython310site-packagesstarlettemiddlewareerrors.py", line 151, in __call__
await self.app(scope, receive, send)
File "C:UserstankaAppDataRoamingPythonPython310site-packagesstarlettemiddlewareexceptions.py", line 65, in __call__
await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send)
File "C:UserstankaAppDataRoamingPythonPython310site-packagesstarlette_exception_handler.py", line 64, in wrapped_app
raise exc
File "C:UserstankaAppDataRoamingPythonPython310site-packagesstarlette_exception_handler.py", line 53, in wrapped_app
await app(scope, receive, sender)
File "C:UserstankaAppDataRoamingPythonPython310site-packagesstarletterouting.py", line 756, in __call__
await self.middleware_stack(scope, receive, send)
File "C:UserstankaAppDataRoamingPythonPython310site-packagesstarletterouting.py", line 776, in app
await route.handle(scope, receive, send)
File "C:UserstankaAppDataRoamingPythonPython310site-packagesstarletterouting.py", line 373, in handle
await self.app(scope, receive, send)
File "C:UserstankaAppDataRoamingPythonPython310site-packagesstarletterouting.py", line 96, in app
await wrap_app_handling_exceptions(app, session)(scope, receive, send)
File "C:UserstankaAppDataRoamingPythonPython310site-packagesstarlette_exception_handler.py", line 64, in wrapped_app
raise exc
File "C:UserstankaAppDataRoamingPythonPython310site-packagesstarlette_exception_handler.py", line 53, in wrapped_app
await app(scope, receive, sender)
File "C:UserstankaAppDataRoamingPythonPython310site-packagesstarletterouting.py", line 94, in app
await func(session)
File "C:UserstankaAppDataRoamingPythonPython310site-packagesfastapirouting.py", line 348, in app
await dependant.call(**values)
File "C:UserstankaDesktopCapstone IOTOCPPserver_A.py", line 80, in websocket_endpoint
message = await websocket.receive_text()
File "C:UserstankaAppDataRoamingPythonPython310site-packagesstarlettewebsockets.py", line 138, in receive_text
self._raise_on_disconnect(message)
File "C:UserstankaAppDataRoamingPythonPython310site-packagesstarlettewebsockets.py", line 130, in _raise_on_disconnect
raise WebSocketDisconnect(message["code"], message.get("reason"))
starlette.websockets.WebSocketDisconnect: (1000, None)
INFO: connection closed
INFO: ('127.0.0.1', 64483) - "WebSocket /ws" [accepted]
INFO: connection open
</code>
<code>INFO: Started server process [17852] INFO: Waiting for application startup. INFO: Application startup complete. INFO: Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit) INFO: ('127.0.0.1', 64479) - "WebSocket /ws" [accepted] INFO: connection open server parsed message broadcasted message to all connected clients ERROR: Exception in ASGI application Traceback (most recent call last): File "C:UserstankaAppDataRoamingPythonPython310site-packagesuvicornprotocolswebsocketswebsockets_impl.py", line 244, in run_asgi result = await self.app(self.scope, self.asgi_receive, self.asgi_send) # type: ignore[func-returns-value] File "C:UserstankaAppDataRoamingPythonPython310site-packagesuvicornmiddlewareproxy_headers.py", line 70, in __call__ return await self.app(scope, receive, send) File "C:UserstankaAppDataRoamingPythonPython310site-packagesfastapiapplications.py", line 1054, in __call__ await super().__call__(scope, receive, send) File "C:UserstankaAppDataRoamingPythonPython310site-packagesstarletteapplications.py", line 123, in __call__ await self.middleware_stack(scope, receive, send) File "C:UserstankaAppDataRoamingPythonPython310site-packagesstarlettemiddlewareerrors.py", line 151, in __call__ await self.app(scope, receive, send) File "C:UserstankaAppDataRoamingPythonPython310site-packagesstarlettemiddlewareexceptions.py", line 65, in __call__ await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send) File "C:UserstankaAppDataRoamingPythonPython310site-packagesstarlette_exception_handler.py", line 64, in wrapped_app raise exc File "C:UserstankaAppDataRoamingPythonPython310site-packagesstarlette_exception_handler.py", line 53, in wrapped_app await app(scope, receive, sender) File "C:UserstankaAppDataRoamingPythonPython310site-packagesstarletterouting.py", line 756, in __call__ await self.middleware_stack(scope, receive, send) File "C:UserstankaAppDataRoamingPythonPython310site-packagesstarletterouting.py", line 776, in app await route.handle(scope, receive, send) File "C:UserstankaAppDataRoamingPythonPython310site-packagesstarletterouting.py", line 373, in handle await self.app(scope, receive, send) File "C:UserstankaAppDataRoamingPythonPython310site-packagesstarletterouting.py", line 96, in app await wrap_app_handling_exceptions(app, session)(scope, receive, send) File "C:UserstankaAppDataRoamingPythonPython310site-packagesstarlette_exception_handler.py", line 64, in wrapped_app raise exc File "C:UserstankaAppDataRoamingPythonPython310site-packagesstarlette_exception_handler.py", line 53, in wrapped_app await app(scope, receive, sender) File "C:UserstankaAppDataRoamingPythonPython310site-packagesstarletterouting.py", line 94, in app await func(session) File "C:UserstankaAppDataRoamingPythonPython310site-packagesfastapirouting.py", line 348, in app await dependant.call(**values) File "C:UserstankaDesktopCapstone IOTOCPPserver_A.py", line 80, in websocket_endpoint message = await websocket.receive_text() File "C:UserstankaAppDataRoamingPythonPython310site-packagesstarlettewebsockets.py", line 138, in receive_text self._raise_on_disconnect(message) File "C:UserstankaAppDataRoamingPythonPython310site-packagesstarlettewebsockets.py", line 130, in _raise_on_disconnect raise WebSocketDisconnect(message["code"], message.get("reason")) starlette.websockets.WebSocketDisconnect: (1000, None) INFO: connection closed INFO: ('127.0.0.1', 64483) - "WebSocket /ws" [accepted] INFO: connection open </code>
INFO:     Started server process [17852]
INFO:     Waiting for application startup.
INFO:     Application startup complete.
INFO:     Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)
INFO:     ('127.0.0.1', 64479) - "WebSocket /ws" [accepted]
INFO:     connection open
server parsed message
broadcasted message to all connected clients
ERROR:    Exception in ASGI application
Traceback (most recent call last):
  File "C:UserstankaAppDataRoamingPythonPython310site-packagesuvicornprotocolswebsocketswebsockets_impl.py", line 244, in run_asgi
    result = await self.app(self.scope, self.asgi_receive, self.asgi_send)  # type: ignore[func-returns-value]
  File "C:UserstankaAppDataRoamingPythonPython310site-packagesuvicornmiddlewareproxy_headers.py", line 70, in __call__
    return await self.app(scope, receive, send)
  File "C:UserstankaAppDataRoamingPythonPython310site-packagesfastapiapplications.py", line 1054, in __call__
    await super().__call__(scope, receive, send)
  File "C:UserstankaAppDataRoamingPythonPython310site-packagesstarletteapplications.py", line 123, in __call__
    await self.middleware_stack(scope, receive, send)
  File "C:UserstankaAppDataRoamingPythonPython310site-packagesstarlettemiddlewareerrors.py", line 151, in __call__
    await self.app(scope, receive, send)
  File "C:UserstankaAppDataRoamingPythonPython310site-packagesstarlettemiddlewareexceptions.py", line 65, in __call__
    await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send)
  File "C:UserstankaAppDataRoamingPythonPython310site-packagesstarlette_exception_handler.py", line 64, in wrapped_app
    raise exc
  File "C:UserstankaAppDataRoamingPythonPython310site-packagesstarlette_exception_handler.py", line 53, in wrapped_app
    await app(scope, receive, sender)
  File "C:UserstankaAppDataRoamingPythonPython310site-packagesstarletterouting.py", line 756, in __call__
    await self.middleware_stack(scope, receive, send)
  File "C:UserstankaAppDataRoamingPythonPython310site-packagesstarletterouting.py", line 776, in app
    await route.handle(scope, receive, send)
  File "C:UserstankaAppDataRoamingPythonPython310site-packagesstarletterouting.py", line 373, in handle
    await self.app(scope, receive, send)
  File "C:UserstankaAppDataRoamingPythonPython310site-packagesstarletterouting.py", line 96, in app
    await wrap_app_handling_exceptions(app, session)(scope, receive, send)
  File "C:UserstankaAppDataRoamingPythonPython310site-packagesstarlette_exception_handler.py", line 64, in wrapped_app
    raise exc
  File "C:UserstankaAppDataRoamingPythonPython310site-packagesstarlette_exception_handler.py", line 53, in wrapped_app
    await app(scope, receive, sender)
  File "C:UserstankaAppDataRoamingPythonPython310site-packagesstarletterouting.py", line 94, in app
    await func(session)
  File "C:UserstankaAppDataRoamingPythonPython310site-packagesfastapirouting.py", line 348, in app
    await dependant.call(**values)
  File "C:UserstankaDesktopCapstone IOTOCPPserver_A.py", line 80, in websocket_endpoint
    message = await websocket.receive_text()
  File "C:UserstankaAppDataRoamingPythonPython310site-packagesstarlettewebsockets.py", line 138, in receive_text
    self._raise_on_disconnect(message)
  File "C:UserstankaAppDataRoamingPythonPython310site-packagesstarlettewebsockets.py", line 130, in _raise_on_disconnect
    raise WebSocketDisconnect(message["code"], message.get("reason"))
starlette.websockets.WebSocketDisconnect: (1000, None)
INFO:     connection closed
INFO:     ('127.0.0.1', 64483) - "WebSocket /ws" [accepted]
INFO:     connection open

I am appending my python code for reference.

Server.py

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>from fastapi import FastAPI, WebSocket
from fastapi.responses import HTMLResponse
from fastapi.staticfiles import StaticFiles
from websockets.exceptions import ConnectionClosedError
import asyncio
import uvicorn
from pathlib import Path
from time import sleep
import starlette
app = FastAPI()
current_file = Path(__file__)
current_file_dir = current_file.parent
project_root = current_file_dir
project_root_absolute = project_root.resolve()
static_root_absolute = project_root_absolute
# serve static files
app.mount("/static", StaticFiles(directory=Path(static_root_absolute, 'static')), name="static")
#define message handling
async def server_handle_message(message, ws):
if(message=="messageA"):
# handle message A
await ws.send_text("messageA")
print("handle message A")
# handle message B
elif(message=="messageB"):
await ws.send_text("messageB")
print("handle message B")
else:
pass
# create a WebSocket endpoint
@app.websocket("/ws")
async def websocket_endpoint(websocket: WebSocket):
await websocket.accept()
while True:
# wait for message from client
try:
message = await websocket.receive_text()
await server_handle_message(message,websocket)
print("server parsed message")
await websocket.send_text(message)
print("broadcasted message to all connected clients")
except ConnectionClosedError:
print("Connection Closed Error")
continue
# start the server
if __name__ == "__main__":
clients = []
uvicorn.run(app, host="0.0.0.0", port=8000, ws_ping_interval=600, ws_ping_timeout=60)
</code>
<code>from fastapi import FastAPI, WebSocket from fastapi.responses import HTMLResponse from fastapi.staticfiles import StaticFiles from websockets.exceptions import ConnectionClosedError import asyncio import uvicorn from pathlib import Path from time import sleep import starlette app = FastAPI() current_file = Path(__file__) current_file_dir = current_file.parent project_root = current_file_dir project_root_absolute = project_root.resolve() static_root_absolute = project_root_absolute # serve static files app.mount("/static", StaticFiles(directory=Path(static_root_absolute, 'static')), name="static") #define message handling async def server_handle_message(message, ws): if(message=="messageA"): # handle message A await ws.send_text("messageA") print("handle message A") # handle message B elif(message=="messageB"): await ws.send_text("messageB") print("handle message B") else: pass # create a WebSocket endpoint @app.websocket("/ws") async def websocket_endpoint(websocket: WebSocket): await websocket.accept() while True: # wait for message from client try: message = await websocket.receive_text() await server_handle_message(message,websocket) print("server parsed message") await websocket.send_text(message) print("broadcasted message to all connected clients") except ConnectionClosedError: print("Connection Closed Error") continue # start the server if __name__ == "__main__": clients = [] uvicorn.run(app, host="0.0.0.0", port=8000, ws_ping_interval=600, ws_ping_timeout=60) </code>
from fastapi import FastAPI, WebSocket
from fastapi.responses import HTMLResponse
from fastapi.staticfiles import StaticFiles
from websockets.exceptions import ConnectionClosedError
import asyncio
import uvicorn

from pathlib import Path
from time import sleep
import starlette

app = FastAPI()

current_file = Path(__file__)
current_file_dir = current_file.parent
project_root = current_file_dir
project_root_absolute = project_root.resolve()
static_root_absolute = project_root_absolute


# serve static files
app.mount("/static", StaticFiles(directory=Path(static_root_absolute, 'static')), name="static")


#define message handling
async def server_handle_message(message, ws):
    if(message=="messageA"):
    # handle message A
        await ws.send_text("messageA")
        print("handle message A")

    # handle message B
    elif(message=="messageB"):
        await ws.send_text("messageB")
        print("handle message B")

    else:
        pass


# create a WebSocket endpoint
@app.websocket("/ws")
async def websocket_endpoint(websocket: WebSocket):
    await websocket.accept()

    while True:        


            # wait for message from client
        try:
            message = await websocket.receive_text()
            
            await server_handle_message(message,websocket)

            print("server parsed message")
            
            await websocket.send_text(message)
            print("broadcasted message to all connected clients")
    
        except ConnectionClosedError:
            print("Connection Closed Error")
            continue

# start the server
if __name__ == "__main__":
    clients = []
    uvicorn.run(app, host="0.0.0.0", port=8000, ws_ping_interval=600, ws_ping_timeout=60)

client.py

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>import asyncio
import websockets
import sys
def handle_message(message):
if(message=="some message A"):
print("client received msg A")
elif(message=="some message B"):
print("client received msg B")
else:
pass
async def receive_messages(ws):
message = await ws.recv()
print(f"Received message: {message}")
handle_message(message)
print("message was parsed")
async def send_messages(ws):
message = input("Enter message: ")
if(message=="some text A"):
print("text A")
await ws.send("message A")
elif(message=="some text B"):
print("text B")
await ws.send("message B")
else:
await ws.send(message)
async def main():
try:
async with websockets.connect("ws://localhost:8000/ws") as websocket:
group=asyncio.gather(receive_messages(websocket), send_messages(websocket))
await group
except TimeoutError:
pass
if __name__ == "__main__":
while True:
try:
asyncio.run(main())
print("try to run main() routine")
except websockets.exceptions.ConnectionClosed:
print("websocket Exception - Connection closed. Do cleanup")
continue
except asyncio.exceptions.TimeoutError:
print("Asyncio exception - timeout error. Do cleanup")
continue
except websockets.ConnectionClosed:
print("websocket Connection closed. Do cleanup")
continue
except KeyboardInterrupt:
print("Keyboard interrupted")
sys.exit(0)
</code>
<code>import asyncio import websockets import sys def handle_message(message): if(message=="some message A"): print("client received msg A") elif(message=="some message B"): print("client received msg B") else: pass async def receive_messages(ws): message = await ws.recv() print(f"Received message: {message}") handle_message(message) print("message was parsed") async def send_messages(ws): message = input("Enter message: ") if(message=="some text A"): print("text A") await ws.send("message A") elif(message=="some text B"): print("text B") await ws.send("message B") else: await ws.send(message) async def main(): try: async with websockets.connect("ws://localhost:8000/ws") as websocket: group=asyncio.gather(receive_messages(websocket), send_messages(websocket)) await group except TimeoutError: pass if __name__ == "__main__": while True: try: asyncio.run(main()) print("try to run main() routine") except websockets.exceptions.ConnectionClosed: print("websocket Exception - Connection closed. Do cleanup") continue except asyncio.exceptions.TimeoutError: print("Asyncio exception - timeout error. Do cleanup") continue except websockets.ConnectionClosed: print("websocket Connection closed. Do cleanup") continue except KeyboardInterrupt: print("Keyboard interrupted") sys.exit(0) </code>
import asyncio
import websockets
import sys

def handle_message(message):
    if(message=="some message A"):
        print("client received msg A")
    
    elif(message=="some message B"):
        print("client received msg B")
    
    else:
        pass

async def receive_messages(ws):

        message = await ws.recv()
        print(f"Received message: {message}")
        handle_message(message)
        print("message was parsed")

async def send_messages(ws):

    message = input("Enter message: ")
        
    if(message=="some text A"):
        print("text A")
        await ws.send("message A")
    
    elif(message=="some text B"):
        print("text B")
        await ws.send("message B")

    else:
       await ws.send(message)

async def main():
    try:
        async with websockets.connect("ws://localhost:8000/ws") as websocket:
            group=asyncio.gather(receive_messages(websocket), send_messages(websocket))
            await group
    except TimeoutError:
        pass

if __name__ == "__main__":
    while True:

        try:
            asyncio.run(main())
            print("try to run main() routine")

        except websockets.exceptions.ConnectionClosed:
            print("websocket Exception - Connection closed.  Do cleanup")
            continue
        
        except asyncio.exceptions.TimeoutError:
            print("Asyncio exception - timeout error.  Do cleanup")
            continue

        except websockets.ConnectionClosed:
            print("websocket Connection closed.  Do cleanup")
            continue

        except KeyboardInterrupt:
            print("Keyboard interrupted")
            sys.exit(0)     

I have tried reading the FastApi documentation but could not find any solutions.
I have also tried to adjust the websocket ping interval and ping timeout as shown below:

But the problem still persists.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code># start the server
if __name__ == "__main__":
clients = []
uvicorn.run(app, host="0.0.0.0", port=8000, ws_ping_interval=600, ws_ping_timeout=60)
</code>
<code># start the server if __name__ == "__main__": clients = [] uvicorn.run(app, host="0.0.0.0", port=8000, ws_ping_interval=600, ws_ping_timeout=60) </code>
# start the server
if __name__ == "__main__":
    clients = []
    uvicorn.run(app, host="0.0.0.0", port=8000, ws_ping_interval=600, ws_ping_timeout=60)

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật