Skip to content

Commit 5b4407a

Browse files
authored
Fix race condition where the error box didn't always display (#788)
1 parent 5e02e37 commit 5b4407a

File tree

4 files changed

+84
-1
lines changed

4 files changed

+84
-1
lines changed

mesop/examples/__init__.py

+1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
from mesop.examples import (
1717
error_no_stateclass_decorator as error_no_stateclass_decorator,
1818
)
19+
from mesop.examples import event_handler_error as event_handler_error
1920
from mesop.examples import focus_component as focus_component
2021
from mesop.examples import generator as generator
2122
from mesop.examples import grid as grid

mesop/examples/event_handler_error.py

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import asyncio
2+
import time
3+
from typing import Generator
4+
5+
import mesop as me
6+
7+
8+
@me.page(path="/event_handler_error")
9+
def page():
10+
me.text("Hello, world!")
11+
me.button(label="Regular event handler", on_click=on_click)
12+
me.button(label="Generator event handler", on_click=on_click_generator)
13+
me.button(label="Yield from event handler", on_click=on_click_yield_from)
14+
me.button(
15+
label="Async generator event handler", on_click=on_click_async_generator
16+
)
17+
18+
19+
def on_click(e: me.ClickEvent):
20+
raise Exception("Error in on_click.")
21+
22+
23+
def on_click_generator(e: me.ClickEvent):
24+
yield
25+
raise Exception("Error in on_click_generator.")
26+
27+
28+
def on_click_yield_from(e: me.ClickEvent) -> Generator[None, None, None]:
29+
yield from a_generator()
30+
31+
32+
def a_generator():
33+
yield
34+
time.sleep(0.2)
35+
raise Exception("Error in a_generator.")
36+
37+
38+
async def on_click_async_generator(e: me.ClickEvent):
39+
await asyncio.sleep(0.2)
40+
yield
41+
raise Exception("Error in on_click_async_generator.")
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import {test, expect} from '@playwright/test';
2+
3+
test('event handler error message is shown', async ({page}) => {
4+
await page.goto('/event_handler_error');
5+
6+
// Regular event handler
7+
await page.getByRole('button', {name: 'Regular event handler'}).click();
8+
await expect(
9+
page.getByText('Error in on_click.', {exact: true}),
10+
).toBeVisible();
11+
await page.locator('button').filter({hasText: 'close'}).click();
12+
13+
// Generator event handler
14+
await page
15+
.getByRole('button', {name: 'Generator event handler', exact: true})
16+
.click();
17+
await expect(
18+
page.getByText('Error in on_click_generator.', {exact: true}),
19+
).toBeVisible();
20+
await page.locator('button').filter({hasText: 'close'}).click();
21+
22+
// Yield from event handler
23+
await page.getByRole('button', {name: 'Yield from event handler'}).click();
24+
await expect(
25+
page.getByText('Error in a_generator.', {exact: true}),
26+
).toBeVisible();
27+
await page.locator('button').filter({hasText: 'close'}).click();
28+
29+
// Async generator event handler
30+
await page
31+
.getByRole('button', {name: 'Async generator event handler'})
32+
.click();
33+
await expect(
34+
page.getByText('Error in on_click_async_generator.', {exact: true}),
35+
).toBeVisible();
36+
await page.locator('button').filter({hasText: 'close'}).click();
37+
});

mesop/web/src/shell/shell.ts

+5-1
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,11 @@ export class Shell {
9797
{
9898
zone: this.zone,
9999
onRender: async (rootComponent, componentConfigs, jsModules) => {
100+
// Make sure we clear the error *before* the async work, otherwise
101+
// we can hit a weird race condition where the error is cleared
102+
// right away before the user sees the error box.
103+
this.error = undefined;
104+
100105
// Import all JS modules concurrently
101106
await Promise.all(
102107
jsModules.map((modulePath) =>
@@ -113,7 +118,6 @@ export class Shell {
113118
if (componentConfigs.length) {
114119
this.componentConfigs = componentConfigs;
115120
}
116-
this.error = undefined;
117121
},
118122
onCommand: (command) => {
119123
if (command.hasNavigate()) {

0 commit comments

Comments
 (0)