@@ -276,18 +276,18 @@ def double_set_state(event):
276
276
first = await display .page .wait_for_selector ("#first" )
277
277
second = await display .page .wait_for_selector ("#second" )
278
278
279
- assert ( await first .get_attribute ("data-value" )) == "0"
280
- assert ( await second .get_attribute ("data-value" )) == "0"
279
+ await poll ( first .get_attribute ("data-value" )). until_equals ( "0" )
280
+ await poll ( second .get_attribute ("data-value" )). until_equals ( "0" )
281
281
282
282
await button .click ()
283
283
284
- assert ( await first .get_attribute ("data-value" )) == "1"
285
- assert ( await second .get_attribute ("data-value" )) == "1"
284
+ await poll ( first .get_attribute ("data-value" )). until_equals ( "1" )
285
+ await poll ( second .get_attribute ("data-value" )). until_equals ( "1" )
286
286
287
287
await button .click ()
288
288
289
- assert ( await first .get_attribute ("data-value" )) == "2"
290
- assert ( await second .get_attribute ("data-value" )) == "2"
289
+ await poll ( first .get_attribute ("data-value" )). until_equals ( "2" )
290
+ await poll ( second .get_attribute ("data-value" )). until_equals ( "2" )
291
291
292
292
293
293
async def test_use_effect_callback_occurs_after_full_render_is_complete ():
@@ -600,6 +600,40 @@ async def effect(e):
600
600
await asyncio .wait_for (cleanup_ran .wait (), 1 )
601
601
602
602
603
+ async def test_use_async_effect_cleanup_task_error_handled_gradefully ():
604
+ component_hook = HookCatcher ()
605
+ effect_ran = WaitForEvent ()
606
+ cleanup_ran = WaitForEvent ()
607
+
608
+ async def cleanup_task ():
609
+ cleanup_ran .set ()
610
+ raise ValueError ("Something went wrong" )
611
+
612
+ @reactpy .component
613
+ @component_hook .capture
614
+ def ComponentWithAsyncEffect ():
615
+ @reactpy .use_effect (dependencies = None ) # force this to run every time
616
+ async def effect (e ):
617
+ async with e :
618
+ effect_ran .set ()
619
+ return cleanup_task ()
620
+
621
+ return reactpy .html .div ()
622
+
623
+ with assert_reactpy_did_log (
624
+ match_message = r"Error while cleaning up effect" ,
625
+ error_type = ValueError ,
626
+ ):
627
+ async with reactpy .Layout (ComponentWithAsyncEffect ()) as layout :
628
+ await layout .render ()
629
+
630
+ component_hook .latest .schedule_render ()
631
+
632
+ await layout .render ()
633
+
634
+ await asyncio .wait_for (cleanup_ran .wait (), 1 )
635
+
636
+
603
637
async def test_use_async_effect_cancel (caplog ):
604
638
component_hook = HookCatcher ()
605
639
effect_ran = WaitForEvent ()
0 commit comments