@@ -231,27 +231,38 @@ def exit_with_permission_help_text():
231231 print (
232232 "Error: The specified process cannot be attached to due to insufficient permissions.\n "
233233 "See the Python documentation for details on required privileges and troubleshooting:\n "
234- "https://docs.python.org/3.14/howto/remote_debugging.html#permission-requirements\n "
234+ "https://docs.python.org/3/howto/remote_debugging.html#permission-requirements\n " ,
235+ file = sys .stderr ,
235236 )
236237 sys .exit (1 )
237238
238239
239- def _get_awaited_by_tasks (pid : int ) -> list :
240- try :
241- return get_all_awaited_by (pid )
242- except RuntimeError as e :
243- while e .__context__ is not None :
244- e = e .__context__
245- print (f"Error retrieving tasks: { e } " )
246- sys .exit (1 )
247- except PermissionError :
248- exit_with_permission_help_text ()
240+ _TRANSIENT_ERRORS = (RuntimeError , OSError , UnicodeDecodeError , MemoryError )
241+
242+
243+ def _get_awaited_by_tasks (pid : int , retries : int = 3 ) -> list :
244+ for attempt in range (retries + 1 ):
245+ try :
246+ return get_all_awaited_by (pid )
247+ except PermissionError :
248+ exit_with_permission_help_text ()
249+ except ProcessLookupError :
250+ print (f"Error: process { pid } not found." , file = sys .stderr )
251+ sys .exit (1 )
252+ except _TRANSIENT_ERRORS as e :
253+ if attempt < retries :
254+ continue
255+ if isinstance (e , RuntimeError ):
256+ while e .__context__ is not None :
257+ e = e .__context__
258+ print (f"Error retrieving tasks: { e } " , file = sys .stderr )
259+ sys .exit (1 )
249260
250261
251- def display_awaited_by_tasks_table (pid : int ) -> None :
262+ def display_awaited_by_tasks_table (pid : int , retries : int = 3 ) -> None :
252263 """Build and print a table of all pending tasks under `pid`."""
253264
254- tasks = _get_awaited_by_tasks (pid )
265+ tasks = _get_awaited_by_tasks (pid , retries = retries )
255266 table = build_task_table (tasks )
256267 # Print the table in a simple tabular format
257268 print (
@@ -262,10 +273,10 @@ def display_awaited_by_tasks_table(pid: int) -> None:
262273 print (f"{ row [0 ]:<10} { row [1 ]:<20} { row [2 ]:<20} { row [3 ]:<50} { row [4 ]:<50} { row [5 ]:<15} { row [6 ]:<15} " )
263274
264275
265- def display_awaited_by_tasks_tree (pid : int ) -> None :
276+ def display_awaited_by_tasks_tree (pid : int , retries : int = 3 ) -> None :
266277 """Build and print a tree of all pending tasks under `pid`."""
267278
268- tasks = _get_awaited_by_tasks (pid )
279+ tasks = _get_awaited_by_tasks (pid , retries = retries )
269280 try :
270281 result = build_async_tree (tasks )
271282 except CycleFoundException as e :
0 commit comments