-1

I've got some middleware I created for an app that checks a few criteria against a logged in user.

If it fails any of those, it kicks off errors letting the user know.

The problem is that the error is showing up twice at the top of the page.

The middleware looks like this:

class RegistrationMiddleware(object):

    def __init__(self, get_response):
        self.get_response = get_response
        print("In init of middleware")

    def __call__(self, request):
        # Code to be executed for each request before
        # the view (and later middleware) are called.
        print("Pre-view middle")
        response = self.get_response(request)
        # Code to be executed for each request/response after
        # the view is called.
        print("Post-view middle")

        ...logic stuff....

        if invalid_entries:
            for problem_reg in invalid_entries:
                messages.error(
                    request, format_html(
                        """
                        Please either
                        remove or change this registration.
                        """ 
                        )
                    )
        print('end of view reutrning response')
        return response

The error shows up twice on the page.

My console shows something like this:

Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
In init of middleware
Pre-view middle
this is a test of the get_user method
Post-view middle
end of view reutrning response
[25/Feb/2019 09:48:46] "GET /registrations/ HTTP/1.1" 200 21860
[25/Feb/2019 09:48:46] "GET /static/styles.css HTTP/1.1" 200 7082
[25/Feb/2019 09:48:46] "GET /static/registrations/style.css HTTP/1.1" 200 2282
[25/Feb/2019 09:48:46] "GET /static/registrations/index.js HTTP/1.1" 200 1885
[25/Feb/2019 09:48:46] "GET /static/all.min.js HTTP/1.1" 200 3738182
Pre-view middle
Post-view middle
this is a test of the get_user method
end of view reutrning response
Not Found: /favicon.ico
[25/Feb/2019 09:48:47] "GET /favicon.ico HTTP/1.1" 404 2586

I'm not sure middleware is 100% the best solution to check for errors like this, but I need to check that same bit of code on essentially every view in the app so it seems like the right way to handle this.

I'm just trying to make it so it just fires once - either before or after the view renders is fine, but I only need it to show one error.

    {% for message in messages %}
        <div class="alert alert-{{ message.tags }} alert-dismissible mt-4" role="alert">
            <button type="button" class="close" data-dismiss="alert" aria-label="Close">
                <span aria-hidden="true">&times;</span>
            </button>
            {{ message }}
        </div>
    {% endfor %}
Hanny
  • 2,078
  • 6
  • 24
  • 52
  • From your logs, it looks like your middleware is functioning correctly. I'm not sure what you mean about the error showing twice one page... how are you showing errors on page? Is is possible you have multiple items in `invalid_entries`? – Nikolas Stevenson-Molnar Feb 25 '19 at 16:01
  • No - in my dev environment I've got it setup so I have just 1 showing up in `invalid_entries`, but when I refresh the page - that error message shows twice on the screen. In the template it's a simple `{% for message in messages %}` loop – Hanny Feb 25 '19 at 16:05
  • Have you checked the values of `messages` before returning from your middleware above? – Nikolas Stevenson-Molnar Feb 25 '19 at 16:08
  • Negative. I have no checks in there currently against existing messages. – Hanny Feb 25 '19 at 16:16
  • It seems to be something with the page loading the first time: for example, I go to page A, I see duplication of errors. Then to page B, I see 2 errors. Back to page A? I only see one as expected. That's why I was trying to just call it 'once', so to speak. I feel like sometimes it's called twice. – Hanny Feb 25 '19 at 16:18
  • Ok, might be worth inspecting the messages at the end of your middleware with `print(get_messages(request))`. – Nikolas Stevenson-Molnar Feb 25 '19 at 16:19
  • Upon inspection - I can see that it's just one message. I think the problem is that it's adding that same message twice - for example in my console log above you see that line `end of view returning response` fires twice for one call to the server (once before the GET lines, once after). That means the error is being added to messages 'twice', right? – Hanny Feb 25 '19 at 16:26
  • Actually, there are two separate pages requested in your log. The second one is `/favicon.ico`. Your middleware gets a shot at all requests, even if the URL doesn't exist. – Nikolas Stevenson-Molnar Feb 25 '19 at 16:28
  • Could you add your template code (where you're rendering errors) to your question? – Nikolas Stevenson-Molnar Feb 25 '19 at 16:29
  • I've added the template code to the question. I see what you're saying about the favicon now. I wonder if there not being a favicon could be causing the messages to be duplicated since it would be adding a message? I suppose easiest might be to just check if that exact message exists in messages - if so, just pass along the response. – Hanny Feb 25 '19 at 16:33
  • Yes, that could be it. The favicon will trigger your middleware, but since the template isn't rendered, messages aren't iterated and therefore aren't dismissed. Then on next request you end up with multiple messages. – Nikolas Stevenson-Molnar Feb 25 '19 at 16:38
  • Yeah, the inconsistency is what is killing me. Maybe Middleware isn't the answer, but I am pretty sure in this instance it is. Just frustrating because it's very "sometimes it's twice, sometimes it's not" - I appreciate your help in troubleshooting this :) – Hanny Feb 25 '19 at 17:03
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/189010/discussion-between-nikolas-stevenson-molnar-and-hanny). – Nikolas Stevenson-Molnar Feb 25 '19 at 17:04

1 Answers1

0

Having the logic after: response = self.get_response(request) was causing the issue and inconsistent behavior - because the alert was being processed after the view, in turn causing the error to be loaded on the next refresh and rinse and repeat and most of the time the error was duplicated.

Moving it to before the view processing fixed the issue and helped make it consistent.

Hanny
  • 2,078
  • 6
  • 24
  • 52