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

Justpy seems to swallow exceptions in event handlers #52

Closed
mjmare opened this issue Apr 20, 2020 · 15 comments
Closed

Justpy seems to swallow exceptions in event handlers #52

mjmare opened this issue Apr 20, 2020 · 15 comments

Comments

@mjmare
Copy link

mjmare commented Apr 20, 2020

I'd made a programming error in a button handler. However no exception appeared and the program kept running (without the intended behaviour obviously). Also in the PyCharm no exception was caught.

BTW JustPy is a godsend. Please promote it more!

@elimintz
Copy link
Collaborator

Try setting `LOGGING_LEVEL = DEBUG' in justpy.env

In the new version coming out soon you will get full trace with this setting.

Thank you for your kind words. Do you have any suggestions how I can promote JustPy better?
What do you use JustPy for and what did you use before?

@mjmare
Copy link
Author

mjmare commented Apr 20, 2020

Cool. Can't wait for the next version.

I tipped Michael Kennedy of the Talk Python podcast to interview you ;-)

I've been searching for a full python web solution for a long time. The regular python REST API + javascript frontend just feels cumbersome (and dirty). However if you have to use JS, than Vue.js and Quasar are excellent choices. I have used them in combination with Pyramid and FastApi (also excellent with great docs). ES6 is palatable but in the end I just don't like javascript and its humongous ecosystem. I've dabbled in GraphQL as a conduit between serverside python and frontend JS but all this shuffling data to and from the browser did not feel efficient.

I'm dabbling in Anvil for the same reason (all python) but it has its limitations as well and it is not open source.
Can't say I grok JustPy completely yet but I find it interesting and refreshing enough to write some programs in it. The areas that are a bit hazy still, are the react method, the delete_flag and the rendering process in general. I'd also be interested in how to use blocking libraries (eg for a database) in combination with JustPy.

As you know the community is the most important asset of any framework. Please consider creating a forum so users of JustPy can help each other.
I think you did a great job with the docs already, but you can't handle all angles.
Some video tutorials would be welcome, I'd say some beginner tutorials but also some that cover non-toy programs. Remember that JustPy is completely different from other web frameworks. It is not like switching from Flask to Django to FastApi (or whatever). Also the Asyncio part is new to even regular python web devs (it certainly is for me). So a tutorial that covers common functionality like user management, database, background tasks, forms would be very welcome. Doesn't have to be production ready, but especially why you do things in a specific way is important.

Finally what people look for in a project is some indication of its viability: frequent code updates, frequent news about the project, quick bug fixes. I know its a lot to ask, but when you grow the community other people will step up, I'm sure.

Keep up the good work!

@elimintz
Copy link
Collaborator

Thank you for the very helpful input which I will take to heart.

Let me just address the delete_flag question as it is relatively straight forward. When a user closes a web page, the framework automatically removes all elements on the server side that correspond to elements on the closed page. Otherwise, JustPy applications would consume too much memory and won't scale well. In some cases, an element on the server side is used in multiple pages, so when any one browser tab closes, you don't want the element on the server side to be removed. That is what the delete_flag is for. It allows a one to many relation between one element on the server side and many elements in different browser tabs. The clock example in the tutorial, https://justpy.io/tutorial/pushing_data/#clock is such a case. The clock face is the same for all users.

As for non-blocking database access, perhaps this would be of interest to you: https://github.com/encode/databases

@mjmare
Copy link
Author

mjmare commented Apr 22, 2020

As for non-blocking database access, perhaps this would be of interest to you: https://github.com/encode/databases

I was aware of that library, however I'd like to use Neo4J. Their python driver is not async yet.

@elimintz
Copy link
Collaborator

You can use the run_in_executor function of the asyncio library to run a Neo4J search in a non-blocking manner: https://docs.python.org/3/library/asyncio-eventloop.html#executing-code-in-thread-or-process-pools

@mjmare
Copy link
Author

mjmare commented Apr 22, 2020

Ok will try that. Really need to learn Asyncio.

@mjmare mjmare closed this as completed Apr 22, 2020
@mjmare
Copy link
Author

mjmare commented Apr 27, 2020

LOGGING_LEVEL = DEBUG did not work for me. Still no exceptions raised.
The program found the config file because it finds other settings (like the latency).

@elimintz
Copy link
Collaborator

Please run the following:

import justpy as jp

def my_click(self, msg):
    c += 1
    self.text = 'Clicked'

def debug_test():
    wp = jp.WebPage()
    jp.Div(text='Click Here', classes='border text-lg w-32 m-2 p-2', a=wp, click=my_click)
    return wp

jp.justpy(debug_test)

I get the full traceback when with the error:

UnboundLocalError: local variable 'c' referenced before assignment

Are you getting something else when you run this?

@mjmare
Copy link
Author

mjmare commented Apr 27, 2020

No nothing at all. Neither running normally, nor in the debugger.
Please note that I use PyCharm. However also on the command line I get no errors at all.
In the PyCharm debugger I can trace until the line where the exception occurs. Then: nothing. Weird.

my justpy.env file:

HIGHCHARTS = True
AGGRID = True
LOGGING_LEVEL = DEBUG
#LATENCY = 70
SECRET_KEY = 'omitted'

@elimintz
Copy link
Collaborator

Yes, weird. Just to be 100% sure I ran with your justpy.env and it works.
I use Pycharm pro on Windows and the logging info shows up in the run window.
Do you know where your logging module files show up usually? Maybe you need to import logging and configure this. https://docs.python.org/3/howto/logging.html
I am not an expert on this.

@mjmare
Copy link
Author

mjmare commented Apr 28, 2020

When running with uvicorn (see #63), which shows more logging output, and using this event handler:

    def cancel(comp, msg):
        print('CANCEL')
        raise Exception('Argh')
        msg.page.redirect = '/'

I see this logging output (please the different color):
Screenshot 2020-04-28 at 20 18 59
Anything after the exception is ignored (to be expected after an exception) but no stack trace.

Running PyCharm on MacOS with python 3.7.7. I have this on 2 (similar)machines.

If I look at the source code in justpy.py line 328 I see a catchall exception handler + pass (always dangerous) and, indeed it is triggered when an exception occurs in the event handler. To me that looks like the culprit.

@elimintz
Copy link
Collaborator

elimintz commented Apr 28, 2020

Please look at line 309 in justpy.py which starts handling the exception for event handler. The line number you are referring to is for the 'after' event handler (you are right, I should change that).

I am using Pycharm on windows and have no problem. I will investigate in other environments,

@mjmare
Copy link
Author

mjmare commented Apr 29, 2020

Ah, I see that I jumped to conclusions: indeed, exceptions in before and after events are ignored. Because they are triggered in each request those lines were reached (in the debugger) and I thought that was the cause.

But you are right, the hot spot is in lines 309-314. You are catching the exception and logging it.
I'm not sure whether that is completely appropriate for a programmer error, but you have probably thought it through. Anyway it explains why the exception was not caught in the debugger.

Then, why don't I see the exception in the log? My guess is that there is some log config error/conflict.
I finally saw the error in the log when I added UVICORN_LOGGING_LEVEL = DEBUG to justpy.env (yeah!) So LOGGING_LEVEL = DEBUG is not sufficient!
Hope this helps you to track down the root cause.

Finally I noticed that you use logging.info(), logging.debug() etc. From what I gather from talks and articles you should be creating your own logger and then use it like logger.info() etc instead of the module level logging.info etc. Like:

import logging

logger = logging.getLogger(__name__)

def foo():
    logger.info('Hi, foo')

This enables the user of your library to tune debugging for each library separately.
That being said, I'm always struggling with the logging library ;-)
This is an article I have found useful: https://fangpenlin.com/posts/2012/08/26/good-logging-practice-in-python/

@elimintz
Copy link
Collaborator

Thanks, will review the article.

@mjmare
Copy link
Author

mjmare commented May 9, 2020

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants