fix exception thrown but not shown in DOM in event handler (#1131)

* fix exception not thrown in event handler

* fix implicit display test

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
This commit is contained in:
Madhur Tandon
2023-01-25 20:08:05 +05:30
committed by GitHub
parent 4124bb5edc
commit 697ac9de9a
4 changed files with 43 additions and 8 deletions

View File

@@ -1,7 +1,7 @@
import { htmlDecode, ensureUniqueId, createDeprecationWarning } from '../utils';
import type { Interpreter } from '../interpreter';
import { getLogger } from '../logger';
import { pyExec } from '../pyexec';
import { pyExec, displayPyException } from '../pyexec';
import { _createAlertBanner } from '../exceptions';
import { robustFetch } from '../fetch';
import { PyScriptApp } from '../main';
@@ -183,7 +183,12 @@ function createElementsWithEventListeners(interpreter: Interpreter, pyAttribute:
}
} else {
el.addEventListener(event, () => {
interpreter.run(handlerCode);
try {
interpreter.run(handlerCode)
}
catch (err) {
displayPyException(err, el.parentElement);
}
});
}
// TODO: Should we actually map handlers in JS instead of Python?

View File

@@ -52,7 +52,7 @@ export function pyDisplay(interpreter: Interpreter, obj: any, kwargs: object) {
}
}
function displayPyException(err: any, errElem: HTMLElement) {
export function displayPyException(err: any, errElem: HTMLElement) {
//addClasses(errElem, ['py-error'])
const pre = document.createElement('pre');
pre.className = 'py-error';

View File

@@ -43,6 +43,30 @@ class TestBasic(PyScriptTest):
assert tb_lines[0] == "Traceback (most recent call last):"
assert tb_lines[-1] == "Exception: this is an error"
def test_python_exception_in_event_handler(self):
self.pyscript_run(
"""
<button py-click="onclick()">Click me</button>
<py-script>
def onclick():
raise Exception("this is an error inside handler")
</py-script>
"""
)
self.page.locator("button").click()
## error in console
tb_lines = self.console.error.lines[-1].splitlines()
assert tb_lines[0] == "[pyexec] Python exception:"
assert tb_lines[1] == "Traceback (most recent call last):"
assert tb_lines[-1] == "Exception: this is an error inside handler"
## error in DOM
tb_lines = self.page.locator(".py-error").inner_text().splitlines()
assert tb_lines[0] == "Traceback (most recent call last):"
assert tb_lines[-1] == "Exception: this is an error inside handler"
def test_execution_in_order(self):
"""
Check that they py-script tags are executed in the same order they are

View File

@@ -109,18 +109,24 @@ class TestOutput(PyScriptTest):
def display_hello():
# this fails because we don't have any implicit target
# from event handlers
display('hello')
display('hello world')
</py-script>
<button id="my-button" py-onClick="display_hello()">Click me</button>
"""
)
self.page.locator("text=Click me").click()
text = self.page.text_content("body")
assert "hello" not in text
self.check_js_errors(
"Implicit target not allowed here. Please use display(..., target=...)"
## error in console
tb_lines = self.console.error.lines[-1].splitlines()
assert tb_lines[0] == "[pyexec] Python exception:"
assert tb_lines[1] == "Traceback (most recent call last):"
assert (
tb_lines[-1]
== "Exception: Implicit target not allowed here. Please use display(..., target=...)"
)
text = self.page.text_content("body")
assert "hello world" not in text
def test_explicit_target_pyscript_tag(self):
self.pyscript_run(
"""