Simon Willison
Simon Willison
Proposed hook design: ```python @hookspec def handle_exception(datasette, request, exception): """Handle an uncaught exception""" ``` It takes `request` in case it needs to render a template and pass the request to...
... maybe it should take `send`? But then how would plugins know that another plugin hadn't already used `send` to send a response, and avoid two trying to send at...
It's weird to return a `Response` though because the code in question lives in `DatasetteRouter` which currently works outside of the layer where responses happen - everything in that class...
Returning a `Response` is by far the most intuitive way to design this though. Plugin authors shouldn't care that `DatasetteRouter` (an undocumented internal API of Datasette) doesn't currently handle responses.
Design decision: ```python @hookspec def handle_exception(datasette, request, exception): """Handle an uncaught exception. Can return a Response or None.""" ``` It will also support returning an awaitable, using the `await_me_maybe` pattern.
I'll implement this hook and then release it as `0.62a1`.
In `DatasetteRouter` I'm going to rename `handle_500` to `handle_exception` because it already deals with error codes other than 500 (`Forbidden` exceptions become 403 and `Base400` become 400).
Had to lookup that `Base400` thing: https://github.com/simonw/datasette/blob/950cc7677f65aa2543067b3bbfc2b6acb98b62c8/datasette/utils/asgi.py#L16-L29
I need to refactor this code so that `Forbidden` exceptions are handled separately. Reason is that those already have a plugin hook of their own: https://github.com/simonw/datasette/blob/8188f55efc0fcca1be692b0d0c875f2d1ee99f17/datasette/app.py#L1384-L1395 My first attempt at...
I think this is the right place to move the code to catch `Forbidden` exceptions (and forwards them to that plugin hook): https://github.com/simonw/datasette/blob/8188f55efc0fcca1be692b0d0c875f2d1ee99f17/datasette/app.py#L1269-L1278