#6233·nicegui

`ui.on_exception` 仍然无法捕获异步 `Event` 订阅者和异步 `validation` 函数的异常 (对 #5945 的跟进)

作者: evnchn创建于 2026年8月3日更新于 2026年8月23日
标签bug

---- Case A: a nicegui.Event subscriber ----

async def test_A1_sync_subscriber(user: User, caplog: pytest.LogCaptureFixture): seen: list[Exception] = []

@ui.page('/')
def page():
    event: Event[[]] = Event()

    def subscriber():                       # sync
        raise RuntimeError('boom')

    event.subscribe(subscriber)
    ui.on_exception(seen.append)
    ui.button('fire', on_click=lambda: event.emit())

await user.open('/')
user.find('fire').click()
await asyncio.sleep(0.1)
caplog.records.clear()
assert len(seen) == 1, f'ui.on_exception saw {len(seen)}, expected 1'

async def test_A2_async_subscriber(user: User, caplog: pytest.LogCaptureFixture): seen: list[Exception] = []

@ui.page('/')
def page():
    event: Event[[]] = Event()

    async def subscriber():                 # async -- the only difference
        raise RuntimeError('boom')

    event.subscribe(subscriber)
    ui.on_exception(seen.append)
    ui.button('fire', on_click=lambda: event.emit())

await user.open('/')
user.find('fire').click()
await asyncio.sleep(0.1)
caplog.records.clear()
assert len(seen) == 1, f'ui.on_exception saw {len(seen)}, expected 1'

---- Case B: a validation function ----

async def test_B1_sync_validation(user: User, caplog: pytest.LogCaptureFixture): seen: list[Exception] = []

def check(value):                           # sync
    raise RuntimeError('boom')

@ui.page('/')
def page():
    ui.on_exception(seen.append)
    field = ui.input('field', validation=check)
    ui.button('validate', on_click=lambda: field.validate(return_result=False))

await user.open('/')
user.find('validate').click()
await asyncio.sleep(0.1)
caplog.records.clear()
assert len(seen) == 1, f'ui.on_exception saw {len(seen)}, expected 1'

async def test_B2_async_validation(user: User, caplog: pytest.LogCaptureFixture): seen: list[Exception] = []

async def check(value):                     # async -- the only difference
    raise RuntimeError('boom')

@ui.page('/')
def page():
    ui.on_exception(seen.append)
    field = ui.input('field', validation=check)
    ui.button('validate',

内容来源: zauberzeug/nicegui