caketop / python-starlark-go

🐍 Python bindings for starlark-go 🐍
https://python-starlark-go.readthedocs.io/
Apache License 2.0
20 stars 7 forks source link

Evaluation errors missing context while syntax errors have them #142

Closed colindean closed 1 year ago

colindean commented 1 year ago

When I encounter an evaluation error, I am not given any context, e.g. method name, line, etc.

$ python3 test.py .vela.star 
Traceback (most recent call last):
  File "/Users/colin/Source/myproject/python-poetry/test.py", line 10, in <module>
    print(s.eval("main([])"))
starlark_go.errors.EvalError: unknown binary op: NoneType | dict

I am given this information for syntax errors:

$ python3 test.py .vela.star 
Traceback (most recent call last):
  File "/Users/colin/Source/myproject/python-poetry/test.py", line 8, in <module>
    s.exec(input_file.read())
starlark_go.errors.ResolveError: <expr>:140:1: if statement not within a function

Perhaps the user can be given the context.

jordemort commented 1 year ago

If you catch the EvalError, is there anything in the .backtrace property? That should map to https://pkg.go.dev/go.starlark.net@v0.0.0-20230122040757-066229b0515d/starlark#EvalError.Backtrace

colindean commented 1 year ago

Yes!

from starlark_go.errors import EvalError
try:
    print(s.eval("main([])"))
except EvalError as e:
    print(e.backtrace)

produces

$ python3 test.py .vela.star 
Traceback (most recent call last):
  <expr>:1:5: in <expr>
  <expr>:143:10: in main
Error: unknown binary op: NoneType | dict

when I inject an error. I fixed the original error; there was a missing return statement ;-)

Could the top of that stack be added to the EvalError message text?

jordemort commented 1 year ago

Probably, it looks like EvalError exposes a CallStack full of CallFrames, each of which has a syntax.Position.

We would probably want to add function_name, line, and column members to the Python EvalError, add additional parameters to hold them to the C wrapper for its constructor, and then populate them from either the first or the last CallFrame when an EvalError is raised. Not sure what the right thing to do would be if the CallStack is empty, probably just "unknown", 0, 0.