@@ -233,7 +233,7 @@ def insert_callback(
233
233
long = None ,
234
234
manager = None ,
235
235
running = None ,
236
- dynamic_creator = False ,
236
+ dynamic_creator : Optional [ bool ] = False ,
237
237
no_output = False ,
238
238
):
239
239
if prevent_initial_call is None :
@@ -279,6 +279,14 @@ def insert_callback(
279
279
return callback_id
280
280
281
281
282
+ def _set_side_update (ctx , response ) -> bool :
283
+ side_update = dict (ctx .updated_props )
284
+ if len (side_update ) > 0 :
285
+ response ["sideUpdate" ] = side_update
286
+ return True
287
+ return False
288
+
289
+
282
290
# pylint: disable=too-many-branches,too-many-statements
283
291
def register_callback (
284
292
callback_list , callback_map , config_prevent_initial_callbacks , * _args , ** _kwargs
@@ -350,7 +358,7 @@ def add_context(*args, **kwargs):
350
358
"callback_context" , AttributeDict ({"updated_props" : {}})
351
359
)
352
360
callback_manager = long and long .get ("manager" , app_callback_manager )
353
- app_on_error = kwargs .pop ("app_on_error" , None )
361
+ error_handler = on_error or kwargs .pop ("app_on_error" , None )
354
362
355
363
if has_output :
356
364
_validate .validate_output_spec (insert_output , output_spec , Output )
@@ -361,7 +369,7 @@ def add_context(*args, **kwargs):
361
369
args , inputs_state_indices
362
370
)
363
371
364
- response = {"multi" : True }
372
+ response : dict = {"multi" : True }
365
373
has_update = False
366
374
367
375
if long is not None :
@@ -413,7 +421,6 @@ def add_context(*args, **kwargs):
413
421
triggered_inputs = callback_ctx .triggered_inputs ,
414
422
ignore_register_page = True ,
415
423
),
416
- on_error = on_error or app_on_error ,
417
424
)
418
425
419
426
data = {
@@ -451,10 +458,19 @@ def add_context(*args, **kwargs):
451
458
isinstance (output_value , dict )
452
459
and "long_callback_error" in output_value
453
460
):
454
- error = output_value .get ("long_callback_error" )
455
- raise LongCallbackError (
461
+ error = output_value .get ("long_callback_error" , {} )
462
+ exc = LongCallbackError (
456
463
f"An error occurred inside a long callback: { error ['msg' ]} \n { error ['tb' ]} "
457
464
)
465
+ if error_handler :
466
+ error_handler (exc )
467
+ output_value = NoUpdate ()
468
+ # set_props from the error handler uses the original ctx
469
+ # instead of manager.get_updated_props since it runs in the
470
+ # request process.
471
+ has_update = _set_side_update (callback_ctx , response )
472
+ else :
473
+ raise exc
458
474
459
475
if job_running and output_value is not callback_manager .UNDEFINED :
460
476
# cached results.
@@ -478,16 +494,15 @@ def add_context(*args, **kwargs):
478
494
except PreventUpdate as err :
479
495
raise err
480
496
except Exception as err : # pylint: disable=broad-exception-caught
481
- if on_error :
482
- output_value = on_error (err )
483
- elif app_on_error :
484
- output_value = app_on_error (err )
497
+ if error_handler :
498
+ error_handler (err )
499
+ if not multi :
500
+ output_value = NoUpdate ()
501
+ else :
502
+ output_value = [NoUpdate for _ in output_spec ]
485
503
else :
486
504
raise err
487
505
488
- if NoUpdate .is_no_update (output_value ):
489
- raise PreventUpdate
490
-
491
506
component_ids = collections .defaultdict (dict )
492
507
493
508
if has_output :
@@ -508,12 +523,12 @@ def add_context(*args, **kwargs):
508
523
)
509
524
510
525
for val , spec in zip (flat_output_values , output_spec ):
511
- if isinstance (val , NoUpdate ):
526
+ if NoUpdate . is_no_update (val ):
512
527
continue
513
528
for vali , speci in (
514
529
zip (val , spec ) if isinstance (spec , list ) else [[val , spec ]]
515
530
):
516
- if not isinstance (vali , NoUpdate ):
531
+ if not NoUpdate . is_no_update (vali ):
517
532
has_update = True
518
533
id_str = stringify_id (speci ["id" ])
519
534
prop = clean_property_name (speci ["property" ])
@@ -527,10 +542,7 @@ def add_context(*args, **kwargs):
527
542
flat_output_values = []
528
543
529
544
if not long :
530
- side_update = dict (callback_ctx .updated_props )
531
- if len (side_update ) > 0 :
532
- has_update = True
533
- response ["sideUpdate" ] = side_update
545
+ has_update = _set_side_update (callback_ctx , response ) or has_update
534
546
535
547
if not has_update :
536
548
raise PreventUpdate
0 commit comments