The GitHub Actions job "Required Checks" on texera.git/gh-readonly-queue/main/pr-8768-5945cc81858e33db3d5280e9913e089f2035b3a6 has failed. Run started by GitHub user Xiao-zhen-Liu (triggered by Xiao-zhen-Liu).
Head commit for run: 57b7ae7b2c5c02a04e84a81645825422cd8780d4 / Suryaa Charan <[email protected]> feat(pyamber): explain Python UDF load errors with cause and fix (#8768) ### What changes were proposed in this PR? When a Python UDF fails to load, the error now says what to fix. The existing "There should be one and only one Operator defined" sentence stays first, so anything matching on it still works. The line number and fix are attached as a note to the original exception, so its type, message and attributes stay as raised. The RPC server now includes exception notes in the `ControlError` message, which is what the Static Error tab shows. | Mistake | Message now adds | |---|---| | No class (e.g. the whole template left commented out) | `No Operator class was found. Uncomment or write exactly one class...` | | Method doesn't match the base class | `WrapperClass subclasses UDFOperatorV2 but does not implement process_tuple. If you meant process_table, subclass UDFTableOperator instead.` | | Two classes | `Found 2: FirstOperator, SecondOperator. Keep one and delete or comment out the others.` | | Missing `from pytexera import *` | `name 'UDFOperatorV2' is not defined (line 2 of the UDF code). Add from pytexera import * at the top of the UDF.` | | `@overrides` on the wrong method | the base class to method pairing | | A class with two pytexera bases | `X uses more than one base class (UDFOperatorV2, UDFTableOperator). Subclass exactly one.` | | Any other load error | the line number in the user's code | Before and after, in the Static Error tab. Before is the untouched template; after is a class with the wrong method: | Before | After | |---|---| | <img width="800" height="288" alt="load-before" src="https://github.com/user-attachments/assets/bd2ac22c-1953-435c-b3d5-0cf2e6f0ddda" />| <img width="800" height="348" alt="load-after" src="https://github.com/user-attachments/assets/53985c6f-9ad3-4d93-aed1-0974d14e85ad" /> | Missing import, after: <img width="800" height="303" alt="load-after-import" src="https://github.com/user-attachments/assets/c1ed1322-f7d0-4937-8aa2-848917a115ba" /> ### Any related issues, documentation, discussions? Part of #8736. Split out of #8737 as the reviewer asked. ### How was this PR tested? New tests in `test_executor_manager.py` cover each case above, plus a syntax error, a `KeyError` and a custom exception at load time (both keep their own message and get the hint as a note), a class alias, and a `LoopEndOperator` subclass. `test_async_rpc_server.py` covers notes in `ControlError`, and loads a broken UDF inside a handler to check the message that gets sent back. ``` cd amber pytest -m "not integration" src/test/python/core/architecture/managers/test_executor_manager.py src/test/python/core/architecture/rpc/test_async_rpc_server.py pytest -m "not integration" ruff check src/main/python src/test/python && ruff format --check src/main/python src/test/python ``` The screenshots are from a local Texera built from this branch. The displayed text for those cases is the same after the follow-up commit. Known limitations: UI-parameter source-line mapping relies on the generated hook's reserved name and structure. Runtime traceback locations (e.g., errors inside process_tuple) are not remapped. ### Was this PR authored or co-authored using generative AI tooling? Generated-by: Claude Code (Claude Opus 5.5) --------- Co-authored-by: suryaacharan <[email protected]> Co-authored-by: Claude Opus 5.5 <[email protected]> Report URL: https://github.com/apache/texera/actions/runs/38791367000 With regards, GitHub Actions via GitBox
