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

Convert uncaught exceptions to messages.error #1162

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.d/+convert-exceptions-to-messages.changed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Htmx: Otherwise uncaught exceptions are caught, logged and converted to messages.error.
21 changes: 20 additions & 1 deletion src/argus/htmx/middleware.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import logging

from django.conf import settings
from django.contrib.auth.views import redirect_to_login
from django.http import HttpResponse
Expand All @@ -6,8 +8,11 @@
from django.utils.encoding import force_str
from django_htmx.http import HttpResponseClientRedirect
from django.contrib import messages

from .request import HtmxHttpRequest

LOG = logging.getLogger(__name__)


class LoginRequiredMiddleware:
def __init__(self, get_response):
Expand Down Expand Up @@ -61,6 +66,14 @@ class HtmxMessageMiddleware(MiddlewareMixin):

TEMPLATE = "messages/_notification_messages_htmx_append.html"

def process_exception(self, request, exception):
error_msg = "500 Internal Server Error"
if str(exception):
error_msg += f": {exception}"
messages.error(request, error_msg)
LOG.error(error_msg)
return None
Comment on lines +69 to +75
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wait, now that I think about this. I don't think we should be returning the raw exception message to the user. This could lead to leaking sensitve information to the user which is a security risk


def process_response(self, request: HtmxHttpRequest, response: HttpResponse) -> HttpResponse:
if not request.htmx:
return response
Expand All @@ -84,7 +97,13 @@ def process_response(self, request: HtmxHttpRequest, response: HttpResponse) ->
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")
error_msg = getattr(response, "content", b"")
if isinstance(error_msg, bytes):
error_msg = error_msg.decode("utf-8")
if not error_msg:
error_msg = f"{response.status_code} {response.reason_phrase}"
messages.error(request, f"An unexpected error occured: {error_msg}. Please try again")
LOG.error("Unhandled exception: %s", error_msg)
# 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
Expand Down
Loading