Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug: HTMXRequest not passed to exception handlers, only gets access to standard Request object #2399

Closed
1 of 4 tasks
ThinksFast opened this issue Oct 4, 2023 · 0 comments · Fixed by #2444
Closed
1 of 4 tasks
Labels
Bug 🐛 This is something that is not working as expected Triage Required 🏥 This requires triage

Comments

@ThinksFast
Copy link
Contributor

ThinksFast commented Oct 4, 2023

Description

I am trying to handle exceptions caused during HTMX requests. But it looks like the exception handler only receives a standard request object, even when the routes are set to receive an HTMXRequest.

In the exception handler, the only flag I can find to indicate it's an HTMX request is request._headers.get("hx-request"). We lose context on all other HTMX attributes in the request, which makes it difficult to troubleshoot and handle nicely.

Having access to the original HTMX request attributes can improve the flexibility of exception handling for these cases.

URL to code causing the issue

No response

MCVE

import logging
from typing import Callable

from litestar import Litestar, MediaType, Request, Response, get
from litestar.contrib.htmx.request import HTMXRequest
from litestar.contrib.htmx.response import HTMXTemplate
from litestar.contrib.jinja import JinjaTemplateEngine
from litestar.response import Template
from litestar.status_codes import HTTP_500_INTERNAL_SERVER_ERROR
from litestar.template import TemplateConfig

logger = logging.getLogger("litestar")

html = """
            <html>
                <head>
                    <script src="https://unpkg.com/htmx.org@1.9.6"></script>
                </head>
                <body>
                    <button hx-get="/htmx">Trigger HTMX</button>
                </body>
            </html>
        """


def http_500(request: Request | HTMXRequest, exc: Exception) -> Template:
    """Something broke, lets fix it"""
    request.logger.exception(f"🚨 500 ERROR: something broke on {request.url}: {exc}")

    meta = {
        "title": "500 Error... something broke bad",
        "description": "Sorry about this, we'll work on it",
    }
    return Template(
        template_name="errors/500.html.j2",
        context={
            "request": request,
            "meta": meta,
        },
    )


exception_config: dict[int | type[Exception], Callable] = {
    HTTP_500_INTERNAL_SERVER_ERROR: http_500,
}


@get("/")
async def serveHomepage(request: Request) -> Response:
    return Response(html, media_type=MediaType.HTML)


@get("/htmx")
async def serveHTMXResponse(request: HTMXRequest) -> Template:
    break_here = 1 / 0
    request.logger.info(break_here)

    return HTMXTemplate(template_name="Some HTMX Template")


app = Litestar(
    route_handlers=[serveHomepage, serveHTMXResponse],
    request_class=HTMXRequest,
    debug=True,
    exception_handlers=exception_config,
    template_config=TemplateConfig(
        directory="src/templates", engine=JinjaTemplateEngine
    ),
)

Steps to reproduce

1. Load up the MRE in your favorite IDE
2. Add a breakpoint inside the `http_500` function
3. Run the app in debug mode
4. Open the homepage and click the button.  It should automatically trigger a DivisionByZero exception
5. Your IDE should break in the `http_500` function.
6. Inspect the `request` object.  If it was an `HTMXRequest`, the object type would be `litestar.contrib.htmx.request.HTMXDetails` and you would see attributes for `request.htmx`.

Screenshots

No response

Logs

No response

Litestar Version

Litestar 2.1.1 and Python 3.11.5

Platform

  • Linux
  • Mac
  • Windows
  • Other (Please specify in the description above)

Funding

  • If you would like to see an issue prioritized, make a pledge towards it!
  • We receive the pledge once the issue is completed & verified
Fund with Polar
@ThinksFast ThinksFast added Bug 🐛 This is something that is not working as expected Triage Required 🏥 This requires triage labels Oct 4, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug 🐛 This is something that is not working as expected Triage Required 🏥 This requires triage
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant