-
-
Notifications
You must be signed in to change notification settings - Fork 132
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
Can the expression engine provide context for errors somehow? #493
Comments
Error within declarative widgets are indeed an area where we can improve much. In this specific case, having some try except in initialization may be the best solution since the error is not in the declarative part but simply in the validation of the member. However we could also try to improve error reported in the expression engine for cases when the error occurs at runtime and not at initialization time. I do not have a plan to address this (and right now it is not my top priority) so feel free to investigate if you have time to do so. As a side note, I am considering switching the Bool member for a Coerced bool in widgets because having to explicitly cast to bool feels very unpythonic. |
+1 I've played around with this sort of thing a few times in the past, but never quite had the time to put something together that was comprehensive. As you point out - there's a few different points we'd want to better report the 'declarative stack' as we encounter an error. activation/init being one of them, but also at runtime when for whatever reason we fail to update the state managed by a proxy. |
I pushed a branch https://github.com/nucleic/enaml/compare/main...frmdstryr:declarative-context?expand=1 which helps with the initialization. Would be nice to be able to add lines into the normal traceback if anyone knows how to do that. I'm not sure what to think about saving the fileno/line for each node cost wise, will have to do some testing. Eg from enaml.core.api import Conditional
from enaml.widgets.api import Window, Container, Label, PushButton
enamldef MyContainer(Container): inside_my_container:
Label: my_label:
text = "Hello"
Conditional: cond:
condition = None
PushButton: btn:
text = "Blow up"
clicked :: cond.condition = None
enamldef Main(Window): main:
Container: container:
Label: label1:
text = "Test"
MyContainer: my_container:
pass Will produce this: Traceback (most recent call last):
File "/home/user/projects/enaml/enaml/core/declarative.py", line 185, in initialize
child.initialize()
File "/home/user/projects/enaml/enaml/core/pattern.py", line 38, in initialize
self.refresh_items()
File "/home/user/projects/enaml/enaml/core/conditional.py", line 74, in refresh_items
if self.condition:
TypeError: The 'condition' member on the 'Conditional' object must be of type 'bool'. Got object of type 'NoneType' instead.
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/home/user/micromamba/envs/enaml/bin/enaml-run", line 33, in <module>
sys.exit(load_entry_point('enaml', 'console_scripts', 'enaml-run')())
File "/home/user/projects/enaml/enaml/runner.py", line 71, in main
window.show()
File "/home/user/projects/enaml/enaml/widgets/window.py", line 380, in show
self.initialize()
File "/home/user/projects/enaml/enaml/widgets/window.py", line 158, in initialize
super(Window, self).initialize()
File "/home/user/projects/enaml/enaml/widgets/toolkit_object.py", line 160, in initialize
super(ToolkitObject, self).initialize()
File "/home/user/projects/enaml/enaml/core/declarative.py", line 185, in initialize
child.initialize()
File "/home/user/projects/enaml/enaml/widgets/toolkit_object.py", line 160, in initialize
super(ToolkitObject, self).initialize()
File "/home/user/projects/enaml/enaml/core/declarative.py", line 185, in initialize
child.initialize()
File "/home/user/projects/enaml/enaml/widgets/toolkit_object.py", line 160, in initialize
super(ToolkitObject, self).initialize()
File "/home/user/projects/enaml/enaml/core/declarative.py", line 189, in initialize
raise InitializationError(child, e) from e
enaml.core.declarative.InitializationError: The 'condition' member on the 'Conditional' object must be of type 'bool'. Got object of type 'NoneType' instead.
File "tests/example.enaml", line 14, in Main
File "tests/example.enaml", line 15, in Container
File "tests/example.enaml", line 18, in MyContainer
File "tests/example.enaml", line 8, in Conditional |
If an error occurs in an expression during the initialization it provides very little context as to where the error is making it difficult to debug in more complex applications.
For example this script:
Will generate this error:
The trace shows the initialization stack but no context as to where the Conditional is in the tree. Since the Conditional is an instance of a node in the tree can you think of any way to provide some sort of context?
One thought that comes to mind is having declarative do child initialization in a try except and do some sort of inspection?
The text was updated successfully, but these errors were encountered: