@@ -1020,11 +1020,37 @@ def _schedule_rpc(self, callback: Callable[..., Any], *args: Any, **kwargs: Any)
10201020
10211021 async def run_callback () -> None :
10221022 with kiwipy .capture_exceptions (kiwi_future ):
1023- result = callback (* args , ** kwargs )
1024- while asyncio .isfuture (result ):
1025- result = await result
1023+ try :
1024+ result = callback (* args , ** kwargs )
1025+ except Exception as exc :
1026+ import inspect
1027+ import traceback
1028+
1029+ # Get traceback as a string
1030+ tb_str = '' .join (traceback .format_exception (type (exc ), exc , exc .__traceback__ ))
1031+
1032+ # Attempt to get file and line number where the callback is defined
1033+ # Note: This might fail for certain built-in or dynamically generated functions.
1034+ # If it fails, just skip that part.
1035+ try :
1036+ source_file = inspect .getfile (callback )
1037+ # getsourcelines returns a tuple (list_of_source_lines, starting_line_number)
1038+ _ , start_line = inspect .getsourcelines (callback )
1039+ callback_location = f'{ source_file } :{ start_line } '
1040+ except Exception :
1041+ callback_location = '<unknown location>'
1042+
1043+ # Include the callback name, file/line info, and the full traceback in the message
1044+ raise RuntimeError (
1045+ f"Error invoking callback '{ callback .__name__ } ' at { callback_location } .\n "
1046+ f'Exception: { type (exc ).__name__ } : { exc } \n \n '
1047+ f'Full Traceback:\n { tb_str } '
1048+ ) from exc
1049+ else :
1050+ while asyncio .isfuture (result ):
1051+ result = await result
10261052
1027- kiwi_future .set_result (result )
1053+ kiwi_future .set_result (result )
10281054
10291055 # Schedule the task and give back a kiwi future
10301056 asyncio .run_coroutine_threadsafe (run_callback (), self .loop )
0 commit comments