jonathan-s / django-sockpuppet

Build reactive applications with the django tooling you already know and love.
https://github.com/jonathan-s/django-sockpuppet
MIT License
450 stars 22 forks source link

Exception doesn't trigger #123

Closed paulik123 closed 3 years ago

paulik123 commented 3 years ago

I encountered this very weird issue. In get get_context_data I had this situation. Instead of cache.get_or_set() I mistakenly wrote session.get_or_set(). Django showed no error, neither the reflexError method in the JS controller was called, but get_context_data was called 3 times in row only by doing one reflex.

Here is the relevant code:

def get_context_data(self, *args, **kwargs):
        context = super().get_context_data(*args, **kwargs)
        session = self.request.session

        print("get_context_data", timezone.now(), context.get('stimulus_reflex'))

        if not context.get('stimulus_reflex'):
            # 
        else:
            # some other code
            context['some_condition'] = True

        # This gets called only when get_context_data is called by a reflex right?
        if context.get('some_condition', None):
            # some other code
            session.get_or_set('sdsdsdsd') # here I made the mistake and Django should give me an error.

Here's the print output when I trigger a reflex:

get_context_data 2021-07-13 10:52:56.915132+00:00 True
get_context_data 2021-07-13 10:52:56.915564+00:00 None
get_context_data 2021-07-13 10:52:56.924344+00:00 True

No error is shown and get_context_data is called 3 times. 2 times with context['stimulus_reflex'] == True and one time False. I've watched the network tab in Developer tools and no other http requests are made.

Now for the really weird part:

def get_context_data(self, *args, **kwargs):
        context = super().get_context_data(*args, **kwargs)
        session = self.request.session

        print("get_context_data", timezone.now(), context.get('stimulus_reflex'))

        if not context.get('stimulus_reflex'):
            # 
        else:
            # some other code
            context['some_condition'] = True
            session.get_or_set('sdsdsdsd') # <--- If if move this line here Django shows me an error.

        # This gets called only when get_context_data is called by a reflex right?
        if context.get('some_condition', None):
            # some other code

OUTPUT:

get_context_data 2021-07-13 10:59:42.711633+00:00 True
get_context_data 2021-07-13 10:59:42.711737+00:00 None
get_context_data 2021-07-13 10:59:42.723331+00:00 True
ERROR:root:SockpuppetConsumer failed to re-render http://127.0.0.1:3000/table_arrangement/ AttributeError: 'SessionStore' object has no attribute 'get_or_set'
Traceback (most recent call last):
  File "/home/paulik123/Desktop/work/python/breeze/breezeenv/lib/python3.8/site-packages/sockpuppet/reflex.py", line 39, in get_context_data
    context = view.get_context_data(**{'stimulus_reflex': True})
  File "/home/paulik123/Desktop/work/python/breeze/breeze/breezeapp/views.py", line 107, in get_context_data
    session.get_or_set('sdsdsdsd')
  File "/home/paulik123/Desktop/work/python/breeze/breezeenv/lib/python3.8/site-packages/django/utils/functional.py", line 247, in inner
    return func(self._wrapped, *args)
AttributeError: 'SessionStore' object has no attribute 'get_or_set'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/paulik123/Desktop/work/python/breeze/breezeenv/lib/python3.8/site-packages/sockpuppet/consumer.py", line 214, in reflex_message
    self.render_page_and_broadcast_morph(reflex, selectors, data)
  File "/home/paulik123/Desktop/work/python/breeze/breezeenv/lib/python3.8/site-packages/sockpuppet/consumer.py", line 227, in render_page_and_broadcast_morph
    html = self.render_page(reflex)
  File "/home/paulik123/Desktop/work/python/breeze/breezeenv/lib/python3.8/site-packages/sockpuppet/consumer.py", line 244, in render_page
    reflex.get_context_data(**reflex_context)
  File "/home/paulik123/Desktop/work/python/breeze/breezeenv/lib/python3.8/site-packages/sockpuppet/reflex.py", line 42, in get_context_data
    context = view.get_context_data(**{'stimulus_reflex': True})
  File "/home/paulik123/Desktop/work/python/breeze/breeze/breezeapp/views.py", line 107, in get_context_data
    session.get_or_set('sdsdsdsd')
  File "/home/paulik123/Desktop/work/python/breeze/breezeenv/lib/python3.8/site-packages/django/utils/functional.py", line 247, in inner
    return func(self._wrapped, *args)
AttributeError: 'SessionStore' object has no attribute 'get_or_set'

I still don't know why get_context_data gets called 3 times but at least an error is shown.

I'll reply promptly if you need more info. Thank you.

django-sockpuppet==0.6.0 Django==3.2.4 Python=3.8

jonathan-s commented 3 years ago

Hmm, I'll see if I can replicate this. I'm assuming that this is one of django's generic views, ie not a plain template view. So this PR > https://github.com/jonathan-s/django-sockpuppet/pull/124 should at least reduce the amount of times get_context_data is called by one.

jonathan-s commented 3 years ago

@paulik123, If you've got an open source django repo where I can try this out that would make it a whole lot easier to see what's up.

paulik123 commented 3 years ago

I added you to my private repo. Also, here's a video showing the behaviour

https://user-images.githubusercontent.com/26138821/125740081-a692c2e0-76cb-43a3-ae07-163a3489d5a3.mp4

jonathan-s commented 3 years ago

@paulik123, that was an excellent video. Do you think you could check the browser console as well? Do you get any errors there?

paulik123 commented 3 years ago

https://user-images.githubusercontent.com/26138821/125811731-aa42a1c6-e94a-47a7-83a8-d5401b512a38.mp4

Nothing besides some warnings. I also have

reflexError(element, reflex, error) {
    console.log(element, reflex, error)
  }

inside my controller and it doesn't get called. It's very strange. I solved the problem by just removing that line, but I was curios about what's causing it.

jonathan-s commented 3 years ago

@paulik123 I've verified that the issue is solved by #124, meaning that it is now showing the exception as expected. So I'm going to go ahead and close this now.