8000 Fix #2220 - Avoid DOM notifications on errors (#2226) · pyscript/pyscript@6b1330d · GitHub
[go: up one dir, main page]

Skip to content

Commit 6b1330d

Browse files
Fix #2220 - Avoid DOM notifications on errors (#2226)
* Fix #2220 - Avoid DOM notifications on errors
1 parent 5d75149 commit 6b1330d

File tree

12 files changed

+118
-38
lines changed

12 files changed

+118
-38
lines changed

core/package-lock.json

Lines changed: 16 additions & 31 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

core/package.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@pyscript/core",
3-
"version": "0.6.6",
3+
"version": "0.6.7",
44
"type": "module",
55
"description": "PyScript",
66
"module": "./index.js",
@@ -60,9 +60,9 @@
6060
"dependencies": {
6161
"@ungap/with-resolvers": "^0.1.0",
6262
"@webreflection/idb-map": "^0.3.2",
63-
"add-promise-listener": "^0.1.1",
63+
"add-promise-listener": "^0.1.3",
6464
"basic-devtools": "^0.1.6",
65-
"polyscript": "^0.16.2",
65+
"polyscript": "^0.16.3",
6666
"sabayon": "^0.5.2",
6767
"sticky-module": "^0.1.1",
6868
"to-json-callback": "^0.1.1",
@@ -75,7 +75,7 @@
7575
"@codemirror/state": "^6.4.1",
7676
"@codemirror/view": "^6.34.1",
7777
"@playwright/test": "1.45.3",
78-
"@rollup/plugin-commonjs": "^28.0.0",
78+
"@rollup/plugin-commonjs": "^28.0.1",
7979
"@rollup/plugin-node-resolve": "^15.3.0",
8080
"@rollup/plugin-terser": "^0.4.4",
8181
"@webreflection/toml-j0.4": "^1.1.3",

core/src/config.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,8 @@ for (const [TYPE] of TYPES) {
146146
}
147147
} else if (!parsed?.plugins?.includes(`!${key}`)) {
148148
toBeAwaited.push(value().then(({ default: p }) => p));
149+
} else if (key === "error") {
150+
toBeAwaited.push(value().then(({ notOnDOM }) => notOnDOM()));
149151
}
150152
}
151153

core/src/plugins/error.js

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,28 @@
11
// PyScript Error Plugin
2+
import { buffered } from "polyscript/exports";
23
import { hooks } from "../core.js";
34

5+
let dontBotherDOM = false;
6+
export function notOnDOM() {
7+
dontBotherDOM = true;
8+
}
9+
410
hooks.main.onReady.add(function override(pyScript) {
511
// be sure this override happens only once
612
hooks.main.onReady.delete(override);
713

814
// trap generic `stderr` to propagate to it regardless
915
const { stderr } = pyScript.io;
1016

11-
// override it with our own logic
12-
pyScript.io.stderr = (error, ...rest) => {
17+
const cb = (error, ...rest) => {
1318
notify(error.message || error);
1419
// let other plugins or stderr hook, if any, do the rest
1520
return stderr(error, ...rest);
1621
};
1722

23+
// override it with our own logic
24+
pyScript.io.stderr = pyScript.type === "py" ? cb : buffered(cb);
25+
1826
// be sure uncaught Python errors are also visible
1927
addEventListener("error", ({ message }) => {
2028
if (message.startsWith("Uncaught PythonError")) notify(message);
@@ -30,6 +38,7 @@ hooks.main.onReady.add(function override(pyScript) {
3038
* @param {string} message
3139
*/
3240
export function notify(message) {
41+
if (dontBotherDOM) return;
3342
const div = document.createElement("div");
3443
div.className = "py-error";
3544
div.textContent = message;

core/tests/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,5 @@
1414
a:hover { opacity: 1; }
1515
</style>
1616
</head>
17-
<body><ul><li><strong><span>javascript</span></strong><ul><li><a href="./javascript/async-listener.html">async-listener<small>.html</small></a></li><li><a href="./javascript/config-url.html">config-url<small>.html</small></a></li><li><a href="./javascript/config_type.html">config_type<small>.html</small></a></li><li><strong><a href="./javascript/fetch/index.html">fetch</a></strong></li><li><a href="./javascript/ffi.html">ffi<small>.html</small></a></li><li><a href="./javascript/hooks.html">hooks<small>.html</small></a></li><li><strong><a href="./javascript/issue-2093/index.html">issue-2093</a></strong></li><li><a href="./javascript/js-storage.html">js-storage<small>.html</small></a></li><li><a href="./javascript/js_modules.html">js_modules<small>.html</small></a></li><li><strong><a href="./javascript/loader/index.html">loader</a></strong></li><li><a href="./javascript/mpy.html">mpy<small>.html</small></a></li><li><a href="./javascript/py-terminal-main.html">py-terminal-main<small>.html</small></a></li><li><a href="./javascript/py-terminal-worker.html">py-terminal-worker<small>.html</small></a></li><li><a href="./javascript/py-terminal.html">py-terminal<small>.html</small></a></li><li><a href="./javascript/py-terminals.html">py-terminals<small>.html</small></a></li><li><strong><a href="./javascript/pyodide-cache/index.html">pyodide-cache</a></strong></li><li><a href="./javascript/storage.html">storage<small>.html</small></a></li><li><strong><span>workers</span></strong><ul><li><strong><a href="./javascript/workers/create_named/index.html">create_named</a></strong></li><li><strong><a href="./javascript/workers/mpy/index.html">mpy</a></strong></li><li><strong><a href="./javascript/workers/py/index.html">py</a></strong></li></ul></li></ul></li><li><strong><a href="./manual/index.html">manual</a></strong><ul><li><a href="./manual/all-done.html">all-done<small>.html</small></a></li><li><a href="./manual/async.html">async<small>.html</small></a></li><li><a href="./manual/camera.html">camera<small>.html</small></a></li><li><a href="./manual/click.html">click<small>.html</small></a></li><li><a href="./manual/code-a-part.html">code-a-part<small>.html</small></a></li><li><a href="./manual/combo.html">combo<small>.html</small></a></li><li><a href="./manual/config.html">config<small>.html</small></a></li><li><a href="./manual/create-element.html">create-element<small>.html</small></a></li><li><a href="./manual/dialog.html">dialog<small>.html</small></a></li><li><a href="./manual/display.html">display<small>.html</small></a></li><li><strong><a href="./manual/donkey/index.html">donkey</a></strong></li><li><a href="./manual/error.html">error<small>.html</small></a></li><li><a href="./manual/html-decode.html">html-decode<small>.html</small></a></li><li><a href="./manual/input.html">input<small>.html</small></a></li><li><a href="./manual/interpreter.html">interpreter<small>.html</small></a></li><li><strong><a href="./manual/issue-7015/index.html">issue-7015</a></strong></li><li><a href="./manual/multi.html">multi<small>.html</small></a></li><li><a href="./manual/multiple-editors.html">multiple-editors<small>.html</small></a></li><li><a href="./manual/no-error.html">no-error<small>.html</small></a></li><li><strong><a href="./manual/no_sab/index.html">no_sab</a></strong></li><li><strong><a href="./manual/piratical/index.html">piratical</a></strong></li><li><a href="./manual/py-editor.html">py-editor<small>.html</small></a></li><li><a href="./manual/py-editor-failure.html">py-editor-failure<small>.html</small></a></li><li><strong><a href="./manual/py-terminals/index.html">py-terminals</a></strong><ul><li><a href="./manual/py-terminals/no-repl.html">no-repl<small>.html</small></a></li><li><a href="./manual/py-terminals/repl.html">repl<small>.html</small></a></li></ul></li><li><a href="./manual/py_modules.html">py_modules<small>.html</small></a></li><li><strong><a href="./manual/service-worker/index.html">service-worker</a></strong></li><li><a href="./manual/split-config.html">split-config<small>.html</small></a></li><li><a href="./manual/submit.html">submit<small>.html</small></a></li><li><a href="./manual/target.html">target<small>.html</small></a></li><li><a href="./manual/test_display_HTML.html">test_display_HTML<small>.html</small></a></li><li><a href="./manual/test_when.html">test_when<small>.html</small></a></li><li><a href="./manual/worker.html">worker<small>.html</small></a></li></ul></li><li><strong><a href="./python/index.html">python</a></strong></li></ul></body>
17+
<body><ul><li><strong><span>javascript</span></strong><ul><li><a href="./javascript/async-listener.html">async-listener<small>.html</small></a></li><li><a href="./javascript/config-url.html">config-url<small>.html</small></a></li><li><a href="./javascript/config_type.html">config_type<small>.html</small></a></li><li><strong><a href="./javascript/fetch/index.html">fetch</a></strong></li><li><a href="./javascript/ffi.html">ffi<small>.html</small></a></li><li><a href="./javascript/hooks.html">hooks<small>.html</small></a></li><li><strong><a href="./javascript/issue-2093/index.html">issue-2093</a></strong></li><li><a href="./javascript/js-storage.html">js-storage<small>.html</small></a></li><li><a href="./javascript/js_modules.html">js_modules<small>.html</small></a></li><li><strong><a href="./javascript/loader/index.html">loader</a></strong></li><li><a href="./javascript/mpy-error.html">mpy-error<small>.html</small></a></li><li><a href="./javascript/mpy-no-error.html">mpy-no-error<small>.html</small></a></li><li><a href="./javascript/mpy.html">mpy<small>.html</small></a></li><li><a href="./javascript/py-terminal-main.html">py-terminal-main<small>.html</small></a></li><li><a href="./javascript/py-terminal-worker.html">py-terminal-worker<small>.html</small></a></li><li><a href="./javascript/py-terminal.html">py-terminal<small>.html</small></a></li><li><a href="./javascript/py-terminals.html">py-terminals<small>.html</small></a></li><li><strong><a href="./javascript/pyodide-cache/index.html">pyodide-cache</a></strong></li><li><a href="./javascript/storage.html">storage<small>.html</small></a></li><li><strong><span>workers</span></strong><ul><li><strong><a href="./javascript/workers/create_named/index.html">create_named</a></strong></li><li><strong><a href="./javascript/workers/mpy/index.html">mpy</a></strong></li><li><strong><a href="./javascript/workers/py/index.html">py</a></strong></li></ul></li></ul></li><li><strong><a href="./manual/index.html">manual</a></strong><ul><li><a href="./manual/all-done.html">all-done<small>.html</small></a></li><li><a href="./manual/async.html">async<small>.html</small></a></li><li><a href="./manual/camera.html">camera<small>.html</small></a></li><li><a href="./manual/click.html">click<small>.html</small></a></li><li><a href="./manual/code-a-part.html">code-a-part<small>.html</small></a></li><li><a href="./manual/combo.html">combo<small>.html</small></a></li><li><a href="./manual/config.html">config<small>.html</small></a></li><li><a href="./manual/create-element.html">create-element<small>.html</small></a></li><li><a href="./manual/dialog.html">dialog<small>.html</small></a></li><li><a href="./manual/display.html">display<small>.html</small></a></li><li><strong><a href="./manual/donkey/index.html">donkey</a></strong></li><li><a href="./manual/error.html">error<small>.html</small></a></li><li><a href="./manual/html-decode.html">html-decode<small>.html</small></a></li><li><a href="./manual/input.html">input<small>.html</small></a></li><li><a href="./manual/interpreter.html">interpreter<small>.html</small></a></li><li><strong><a href="./manual/issue-7015/index.html">issue-7015</a></strong></li><li><a href="./manual/multi.html">multi<small>.html</small></a></li><li><a href="./manual/multiple-editors.html">multiple-editors<small>.html</small></a></li><li><a href="./manual/no-error.html">no-error<small>.html</small></a></li><li><strong><a href="./manual/no_sab/index.html">no_sab</a></strong></li><li><strong><a href="./manual/piratical/index.html">piratical</a></strong></li><li><a href="./manual/py-editor.html">py-editor<small>.html</small></a></li><li><a href="./manual/py-editor-failure.html">py-editor-failure<small>.html</small></a></li><li><strong><a href="./manual/py-terminals/index.html">py-terminals</a></strong><ul><li><a href="./manual/py-terminals/no-repl.html">no-repl<small>.html</small></a></li><li><a href="./manual/py-terminals/repl.html">repl<small>.html</small></a></li></ul></li><li><a href="./manual/py_modules.html">py_modules<small>.html</small></a></li><li><strong><a href="./manual/service-worker/index.html">service-worker</a></strong></li><li><a href="./manual/split-config.html">split-config<small>.html</small></a></li><li><a href="./manual/submit.html">submit<small>.html</small></a></li><li><a href="./manual/target.html">target<small>.html</small></a></li><li><a href="./manual/test_display_HTML.html">test_display_HTML<small>.html</small></a></li><li><a href="./manual/test_when.html">test_when<small>.html</small></a></li><li><a href="./manual/worker.html">worker<small>.html</small></a></li></ul></li><li><strong><a href="./python/index.html">python</a></strong></li></ul></body>
1818
</html>

core/tests/javascript/mpy-error.html

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<!doctype html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8" />
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
6+
<script type="module" src="../../dist/core.js"></script>
7+
<script type="mpy">
8+
from pyscript import document
9+
import sys
10+
print("This is an error", file=sys.stderr)
11+
document.documentElement.classList.add("ok");
12+
</script>
13+
</head>
14+
</html>
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<!doctype html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8" />
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
6+
<script type="module" src="../../dist/core.js"></script>
7+
<script type="mpy" config="mpy-no-error.toml">
8+
from pyscript import document
9+
import sys
10+
print("This is an error", file=sys.stderr)
11+
document.documentElement.classList.add("ok");
12+
</script>
13+
</head>
14+
</html>
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
plugins = ["!error"]

core/tests/js_tests.spec.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,3 +138,17 @@ test('Pyodide lockFileURL vs CDN', async ({ page }) => {
138138
const body = await page.evaluate(() => document.body.textContent);
139139
await expect(body).toBe('OK');
140140
});
141+
142+
test('MicroPython buffered error', async ({ page }) => {
143+
await page.goto('http://localhost:8080/tests/javascript/mpy-error.html');
144+
await page.waitForSelector('html.ok');
145+
const body = await page.evaluate(() => document.body.textContent.trim());
146+
await expect(body).toBe('This is an error');
147+
});
148+
149+
test('MicroPython buffered NO error', async ({ page }) => {
150+
await page.goto('http://localhost:8080/tests/javascript/mpy-no-error.html');
151+
await page.waitForSelector('html.ok');
152+
const body = await page.evaluate(() => document.body.textContent.trim());
153+
await expect(body).toBe('');
154+
});

core/tests/manual/error/index.html

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
6+
<title>PyScript Error Bug?</title>
7+
<link rel="stylesheet" href="../../../dist/core.css">
8+
<script type="module" src="../../../dist/core.js"></script>
9+
</head>
10+
<body>
11+
<py-config>
12+
plugins = ["!error"]
13+
</py-config>
14+
<script type="py">
15+
import sys
16+
print("This is normal content")
17+
print("This is error content", file=sys.stderr)
18+
</script>
19+
<!-- Attempt 2; inline config
20+
<script type="py" config='plugins=["!error"]'>
21+
import sys
22+
print("This is normal content")
23+
print("This is error content", file=sys.stderr)
24+
</script> -->
25+
<!-- Attempt 3; external pyscript.toml
26+
<script type="py" config="pyscript.toml">
27+
import sys
28+
print("This is normal content")
29+
print("This is error content", file=sys.stderr)
30+
</script> -->
31+
<!-- Attempt 4; micropython
32+
<script type="mpy">
33+
import sys
34+
print("This is normal content")
35+
print("This is error content", file=sys.stderr)
36+
</script> -->
37+
<div id="result"></div>
38+
</body>
39+
</html>

core/tests/manual/error/pyscript.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
plugins = ["!error"]

core/types/plugins/error.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
export function notOnDOM(): void;
12
/**
23
* Add a banner to the top of the page, notifying the user of an error
34
* @param {string} message

0 commit comments

Comments
 (0)
0