mirror of
https://github.com/pyscript/pyscript.git
synced 2025-12-19 18:27:29 -05:00
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:
@@ -1,7 +1,7 @@
|
|||||||
import { htmlDecode, ensureUniqueId, createDeprecationWarning } from '../utils';
|
import { htmlDecode, ensureUniqueId, createDeprecationWarning } from '../utils';
|
||||||
import type { Interpreter } from '../interpreter';
|
import type { Interpreter } from '../interpreter';
|
||||||
import { getLogger } from '../logger';
|
import { getLogger } from '../logger';
|
||||||
import { pyExec } from '../pyexec';
|
import { pyExec, displayPyException } from '../pyexec';
|
||||||
import { _createAlertBanner } from '../exceptions';
|
import { _createAlertBanner } from '../exceptions';
|
||||||
import { robustFetch } from '../fetch';
|
import { robustFetch } from '../fetch';
|
||||||
import { PyScriptApp } from '../main';
|
import { PyScriptApp } from '../main';
|
||||||
@@ -183,7 +183,12 @@ function createElementsWithEventListeners(interpreter: Interpreter, pyAttribute:
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
el.addEventListener(event, () => {
|
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?
|
// TODO: Should we actually map handlers in JS instead of Python?
|
||||||
|
|||||||
@@ -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'])
|
//addClasses(errElem, ['py-error'])
|
||||||
const pre = document.createElement('pre');
|
const pre = document.createElement('pre');
|
||||||
pre.className = 'py-error';
|
pre.className = 'py-error';
|
||||||
|
|||||||
@@ -43,6 +43,30 @@ class TestBasic(PyScriptTest):
|
|||||||
assert tb_lines[0] == "Traceback (most recent call last):"
|
assert tb_lines[0] == "Traceback (most recent call last):"
|
||||||
assert tb_lines[-1] == "Exception: this is an error"
|
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):
|
def test_execution_in_order(self):
|
||||||
"""
|
"""
|
||||||
Check that they py-script tags are executed in the same order they are
|
Check that they py-script tags are executed in the same order they are
|
||||||
|
|||||||
@@ -109,18 +109,24 @@ class TestOutput(PyScriptTest):
|
|||||||
def display_hello():
|
def display_hello():
|
||||||
# this fails because we don't have any implicit target
|
# this fails because we don't have any implicit target
|
||||||
# from event handlers
|
# from event handlers
|
||||||
display('hello')
|
display('hello world')
|
||||||
</py-script>
|
</py-script>
|
||||||
<button id="my-button" py-onClick="display_hello()">Click me</button>
|
<button id="my-button" py-onClick="display_hello()">Click me</button>
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
self.page.locator("text=Click me").click()
|
self.page.locator("text=Click me").click()
|
||||||
text = self.page.text_content("body")
|
## error in console
|
||||||
assert "hello" not in text
|
tb_lines = self.console.error.lines[-1].splitlines()
|
||||||
self.check_js_errors(
|
assert tb_lines[0] == "[pyexec] Python exception:"
|
||||||
"Implicit target not allowed here. Please use display(..., target=...)"
|
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):
|
def test_explicit_target_pyscript_tag(self):
|
||||||
self.pyscript_run(
|
self.pyscript_run(
|
||||||
"""
|
"""
|
||||||
|
|||||||
Reference in New Issue
Block a user