{"html_url": "https://github.com/simonw/datasette/issues/1770#issuecomment-1214400698", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1770", "id": 1214400698, "node_id": "IC_kwDOBm6k_c5IYki6", "user": {"value": 9599, "label": "simonw"}, "created_at": "2022-08-14T15:25:51Z", "updated_at": "2022-08-14T15:25:51Z", "author_association": "OWNER", "body": "I've tested this with `datasette-sentry` and it works well.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1306492437, "label": "`handle_exception` plugin hook for custom error handling"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1770#issuecomment-1186630298", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1770", "id": 1186630298, "node_id": "IC_kwDOBm6k_c5Guoqa", "user": {"value": 9599, "label": "simonw"}, "created_at": "2022-07-17T23:29:37Z", "updated_at": "2022-07-17T23:29:37Z", "author_association": "OWNER", "body": "Documentation for the new hook: https://docs.datasette.io/en/latest/plugin_hooks.html#handle-exception-datasette-request-exception", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1306492437, "label": "`handle_exception` plugin hook for custom error handling"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1770#issuecomment-1186629556", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1770", "id": 1186629556, "node_id": "IC_kwDOBm6k_c5Guoe0", "user": {"value": 9599, "label": "simonw"}, "created_at": "2022-07-17T23:25:08Z", "updated_at": "2022-07-17T23:25:08Z", "author_association": "OWNER", "body": "Keeping this issue open until I've proven the new plugin hook works by releasing a plugin that uses it.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1306492437, "label": "`handle_exception` plugin hook for custom error handling"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1770#issuecomment-1186620367", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1770", "id": 1186620367, "node_id": "IC_kwDOBm6k_c5GumPP", "user": {"value": 9599, "label": "simonw"}, "created_at": "2022-07-17T22:38:25Z", "updated_at": "2022-07-17T22:38:25Z", "author_association": "OWNER", "body": "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", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1306492437, "label": "`handle_exception` plugin hook for custom error handling"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1770#issuecomment-1186620168", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1770", "id": 1186620168, "node_id": "IC_kwDOBm6k_c5GumMI", "user": {"value": 9599, "label": "simonw"}, "created_at": "2022-07-17T22:37:01Z", "updated_at": "2022-07-17T22:37:01Z", "author_association": "OWNER", "body": "I need to refactor this code so that `Forbidden` exceptions are handled separately.\r\n\r\nReason is that those already have a plugin hook of their own:\r\n\r\nhttps://github.com/simonw/datasette/blob/8188f55efc0fcca1be692b0d0c875f2d1ee99f17/datasette/app.py#L1384-L1395\r\n\r\nMy first attempt at this refactored that entire `handle_exception` method to call the new plugin hook, moving its current implementation into a `datasette/handle_exception.py` default plugin implementation - but it felt weird having that plugin implementation then itself call the `pm.hook.forbidden()` hook.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1306492437, "label": "`handle_exception` plugin hook for custom error handling"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1770#issuecomment-1185937664", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1770", "id": 1185937664, "node_id": "IC_kwDOBm6k_c5Gr_kA", "user": {"value": 9599, "label": "simonw"}, "created_at": "2022-07-15T21:03:09Z", "updated_at": "2022-07-17T22:25:44Z", "author_association": "OWNER", "body": "Design decision:\r\n\r\n```python\r\n@hookspec\r\ndef handle_exception(datasette, request, exception):\r\n \"\"\"Handle an uncaught exception. Can return a Response or None.\"\"\"\r\n```\r\nIt will also support returning an awaitable, using the `await_me_maybe` pattern.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1306492437, "label": "`handle_exception` plugin hook for custom error handling"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1770#issuecomment-1185944799", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1770", "id": 1185944799, "node_id": "IC_kwDOBm6k_c5GsBTf", "user": {"value": 9599, "label": "simonw"}, "created_at": "2022-07-15T21:09:08Z", "updated_at": "2022-07-15T21:09:08Z", "author_association": "OWNER", "body": "Had to lookup that `Base400` thing: https://github.com/simonw/datasette/blob/950cc7677f65aa2543067b3bbfc2b6acb98b62c8/datasette/utils/asgi.py#L16-L29", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1306492437, "label": "`handle_exception` plugin hook for custom error handling"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1770#issuecomment-1185943887", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1770", "id": 1185943887, "node_id": "IC_kwDOBm6k_c5GsBFP", "user": {"value": 9599, "label": "simonw"}, "created_at": "2022-07-15T21:07:53Z", "updated_at": "2022-07-15T21:07:53Z", "author_association": "OWNER", "body": "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).", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1306492437, "label": "`handle_exception` plugin hook for custom error handling"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1770#issuecomment-1185939664", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1770", "id": 1185939664, "node_id": "IC_kwDOBm6k_c5GsADQ", "user": {"value": 9599, "label": "simonw"}, "created_at": "2022-07-15T21:04:19Z", "updated_at": "2022-07-15T21:04:19Z", "author_association": "OWNER", "body": "I'll implement this hook and then release it as `0.62a1`.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1306492437, "label": "`handle_exception` plugin hook for custom error handling"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1770#issuecomment-1185935764", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1770", "id": 1185935764, "node_id": "IC_kwDOBm6k_c5Gr_GU", "user": {"value": 9599, "label": "simonw"}, "created_at": "2022-07-15T21:02:00Z", "updated_at": "2022-07-15T21:02:12Z", "author_association": "OWNER", "body": "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.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1306492437, "label": "`handle_exception` plugin hook for custom error handling"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1770#issuecomment-1185933972", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1770", "id": 1185933972, "node_id": "IC_kwDOBm6k_c5Gr-qU", "user": {"value": 9599, "label": "simonw"}, "created_at": "2022-07-15T21:00:56Z", "updated_at": "2022-07-15T21:00:56Z", "author_association": "OWNER", "body": "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 at the moment works using `send` directly.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1306492437, "label": "`handle_exception` plugin hook for custom error handling"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1770#issuecomment-1185931417", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1770", "id": 1185931417, "node_id": "IC_kwDOBm6k_c5Gr-CZ", "user": {"value": 9599, "label": "simonw"}, "created_at": "2022-07-15T20:59:25Z", "updated_at": "2022-07-15T20:59:25Z", "author_association": "OWNER", "body": "... 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 the same time?", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1306492437, "label": "`handle_exception` plugin hook for custom error handling"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1770#issuecomment-1185929360", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1770", "id": 1185929360, "node_id": "IC_kwDOBm6k_c5Gr9iQ", "user": {"value": 9599, "label": "simonw"}, "created_at": "2022-07-15T20:58:11Z", "updated_at": "2022-07-15T20:58:11Z", "author_association": "OWNER", "body": "Proposed hook design:\r\n```python\r\n@hookspec\r\ndef handle_exception(datasette, request, exception):\r\n \"\"\"Handle an uncaught exception\"\"\"\r\n```\r\nIt takes `request` in case it needs to render a template and pass the request to it.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1306492437, "label": "`handle_exception` plugin hook for custom error handling"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1770#issuecomment-1185925081", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1770", "id": 1185925081, "node_id": "IC_kwDOBm6k_c5Gr8fZ", "user": {"value": 9599, "label": "simonw"}, "created_at": "2022-07-15T20:55:41Z", "updated_at": "2022-07-15T20:56:16Z", "author_association": "OWNER", "body": "I think the hook gets called any time any exception makes it to this function: https://github.com/simonw/datasette/blob/950cc7677f65aa2543067b3bbfc2b6acb98b62c8/datasette/app.py#L1374-L1440\r\n\r\nMultiple plugins can register for the hook. If they return a `Response` then that's returned to the user - if they return `None` then they can quietly do something with the error (log it to Sentry for example) and let some other handler return a response.\r\n\r\nI think Datasette should have a default plugin hook implementation which returns the 500 error page.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 1306492437, "label": "`handle_exception` plugin hook for custom error handling"}, "performed_via_github_app": null}