Skip to content

Commit

Permalink
Show a message when a http error occured during a htmx request
Browse files Browse the repository at this point in the history
  • Loading branch information
elfjes committed Nov 21, 2024
1 parent ef1074c commit ca016f6
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 8 deletions.
9 changes: 3 additions & 6 deletions src/argus_htmx/incidents/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,15 @@

from django.views.decorators.http import require_POST, require_GET
from django.core.paginator import Paginator
from django.http import HttpRequest, HttpResponse, HttpResponseBadRequest
from django_htmx.middleware import HtmxDetails
from django.http import HttpResponse, HttpResponseBadRequest
from django_htmx.http import HttpResponseClientRefresh

from argus.auth.utils import get_preference, save_preference
from argus.incident.models import Incident
from argus.util.datetime_utils import make_aware

from ..request import HtmxHttpRequest

from .constants import ALLOWED_PAGE_SIZES
from .customization import get_incident_table_columns
from .utils import get_filter_function
Expand Down Expand Up @@ -52,10 +53,6 @@ def prefetch_incident_daughters():
)


class HtmxHttpRequest(HttpRequest):
htmx: HtmxDetails


# fetch with htmx
def incident_detail(request, pk: int):
incident = get_object_or_404(Incident, id=pk)
Expand Down
24 changes: 22 additions & 2 deletions src/argus_htmx/middleware.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
from django.conf import settings
from django.contrib.auth.views import redirect_to_login
from django.http import HttpRequest, HttpResponse
from django.http import HttpResponse
from django.template import loader
from django.utils.deprecation import MiddlewareMixin
from django.utils.encoding import force_str
from django.contrib import messages
from .request import HtmxHttpRequest


class LoginRequiredMiddleware:
Expand Down Expand Up @@ -54,7 +56,7 @@ class HtmxMessageMiddleware(MiddlewareMixin):

TEMPLATE = "messages/_notification_messages_htmx_append.html"

def process_response(self, request: HttpRequest, response: HttpResponse) -> HttpResponse:
def process_response(self, request: HtmxHttpRequest, response: HttpResponse) -> HttpResponse:
if not request.htmx:
return response

Expand All @@ -65,5 +67,23 @@ def process_response(self, request: HttpRequest, response: HttpResponse) -> Http
if not response.writable():
return response

# For HTMX error responses, the view should make sure to write the appropriate message to
# django messages framework. However, if it doesn't, we add a (generic) message so that we
# can at least send some indication to the user that something has gone wrong.
if response.status_code >= 400:
storage = messages.get_messages(request)
has_error_message = any("error" in message.tags for message in storage)
storage.used = False
if not has_error_message:
messages.error(request, "An error occured while processing your request, please try again")
# HTMX doesn't swap content for response codes >=400. However, we do want to show
# the new messages, so we need to rewrite the response to 200, and make sure it only
# swaps the oob notification content
response = HttpResponse(
headers={
"HX-Retarget": "#notification-messages .toast",
"HX-Reswap": "beforeend",
}
)
response.write(loader.render_to_string(self.TEMPLATE, request=request))
return response
6 changes: 6 additions & 0 deletions src/argus_htmx/request.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from django.http import HttpRequest
from django_htmx.middleware import HtmxDetails


class HtmxHttpRequest(HttpRequest):
htmx: HtmxDetails

0 comments on commit ca016f6

Please sign in to comment.