Skip to content

Commit

Permalink
πŸ“ Add post about WebSocketException (#20)
Browse files Browse the repository at this point in the history
  • Loading branch information
Kludex committed May 12, 2024
1 parent a9101ec commit f35dcde
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 1 deletion.
4 changes: 3 additions & 1 deletion .github/workflows/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@ jobs:
restore-keys: |
mkdocs-material-
- run: sudo apt-get install libcairo2-dev libfreetype6-dev libffi-dev libjpeg-dev libpng-dev libz-dev
- run: pip install git+https://${GH_TOKEN}@github.com/squidfunk/mkdocs-material-insiders.git pillow cairosvg
- run: pip install --extra-index-url=$EXTRA_INDEX_URL mkdocs-material pillow cairosvg
env:
EXTRA_INDEX_URL: ${{ secrets.EXTRA_INDEX_URL }}
- run: mkdocs gh-deploy --force
env:
GH_TOKEN: ${{ secrets.GH_TOKEN }}
89 changes: 89 additions & 0 deletions docs/blog/posts/websockets_exception.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
---
date: 2024-05-12
categories:
- WebSockets
readtime: 5
---

# Managing Exceptions in WebSockets with FastAPI

In this post, we delve into the management of exceptions in WebSockets, focusing on a potent but often
overlooked feature: the `WebSocketException` offered by [Starlette][starlette].

## Understanding `WebSocketException`

Conceptually, `WebSocketException` enables you to close a WebSocket connection with a specific code and reason
by raising this exception in your WebSocket route. Here's an illustrative example:

```python
from fastapi import FastAPI, WebSocket
from fastapi.exceptions import WebSocketException

app = FastAPI()

@app.websocket("/ws")
async def websocket_endpoint(websocket: WebSocket):
await websocket.accept()
raise WebSocketException(code=1008, reason="Closing the connection...")
```

In this instance, a `WebSocketException` is raised bearing the code `1008` and the explicit reason for closure: `"Closing the connection..."`.

To run this application, first install FastAPI, Uvicorn, and WebSockets:

```bash
pip install fastapi uvicorn websockets
```

Run the application using Uvicorn:

```
uvicorn main:app --reload
```

On opening a WebSocket connection to ws:https://localhost:8000/ws, you will find the connection being closed with focal code
1008 and the attributed reason.

I use wscat for testing WebSocket connections; you can install it with the following command:

```bash
npm install -g wscat
```

A connection is opened with:

```bash
wscat -c ws:https://127.0.0.1:8000/ws
```

## Handle custom exceptions

The `app.exception_handler` can be used to handle custom exceptions. Consider the following sample:

```python
from fastapi import FastAPI, WebSocket
from fastapi.exceptions import WebSocketException

app = FastAPI()

class CustomException(Exception): ...

@app.exception_handler(CustomException)
async def custom_exception_handler(websocket: WebSocket, exc: Exception):
await websocket.close(code=1008, reason="Custom exception")

@app.websocket("/ws")
async def websocket_endpoint(websocket: WebSocket):
await websocket.accept()
raise CustomException()
```

In this example, the client receives a WebSocket closure with code 1008 and the reason "Custom exception"
when the `CustomException` is raised.

Feel free to connect with me on [LinkedIn][linkedin] for any questions or discussions on this topic.

Happy coding! πŸš€

[starlette]: https://www.starlette.io/websockets/
[linkedin]: https://www.linkedin.com/in/marcelotryle/
1 change: 1 addition & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ theme:
features:
- navigation.tabs
- content.code.annotate
- content.code.copy

palette:
# Palette toggle for light mode
Expand Down

0 comments on commit f35dcde

Please sign in to comment.