Add new remote error introspection attrs
To handle both remote cancellation this adds `ContextCanceled.canceller: tuple` the uid of the cancel requesting actor and is expected to be set by the runtime when servicing any remote cancel request. This makes it possible for `ContextCancelled` receivers to know whether "their actor runtime" is the source of the cancellation. Also add an explicit `RemoteActor.src_actor_uid` which better formalizes the notion of "which remote actor" the error originated from. Both of these new attrs are expected to be packed in the `.msgdata` when the errors are loaded locally.proper_breakpoint_hooking
							parent
							
								
									7dd5d8d1f8
								
							
						
					
					
						commit
						e16e7ca82a
					
				|  | @ -18,18 +18,18 @@ | ||||||
| Our classy exception set. | Our classy exception set. | ||||||
| 
 | 
 | ||||||
| """ | """ | ||||||
|  | import builtins | ||||||
|  | import importlib | ||||||
| from typing import ( | from typing import ( | ||||||
|     Any, |     Any, | ||||||
|     Optional, |  | ||||||
|     Type, |     Type, | ||||||
| ) | ) | ||||||
| import importlib |  | ||||||
| import builtins |  | ||||||
| import traceback | import traceback | ||||||
| 
 | 
 | ||||||
| import exceptiongroup as eg | import exceptiongroup as eg | ||||||
| import trio | import trio | ||||||
| 
 | 
 | ||||||
|  | from ._state import current_actor | ||||||
| 
 | 
 | ||||||
| _this_mod = importlib.import_module(__name__) | _this_mod = importlib.import_module(__name__) | ||||||
| 
 | 
 | ||||||
|  | @ -44,7 +44,7 @@ class RemoteActorError(Exception): | ||||||
|     def __init__( |     def __init__( | ||||||
|         self, |         self, | ||||||
|         message: str, |         message: str, | ||||||
|         suberror_type: Optional[Type[BaseException]] = None, |         suberror_type: Type[BaseException] | None = None, | ||||||
|         **msgdata |         **msgdata | ||||||
| 
 | 
 | ||||||
|     ) -> None: |     ) -> None: | ||||||
|  | @ -53,6 +53,10 @@ class RemoteActorError(Exception): | ||||||
|         self.type = suberror_type |         self.type = suberror_type | ||||||
|         self.msgdata = msgdata |         self.msgdata = msgdata | ||||||
| 
 | 
 | ||||||
|  |     @property | ||||||
|  |     def src_actor_uid(self) -> tuple[str, str] | None: | ||||||
|  |         return self.msgdata.get('src_actor_uid') | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| class InternalActorError(RemoteActorError): | class InternalActorError(RemoteActorError): | ||||||
|     ''' |     ''' | ||||||
|  | @ -62,14 +66,21 @@ class InternalActorError(RemoteActorError): | ||||||
|     ''' |     ''' | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | class ContextCancelled(RemoteActorError): | ||||||
|  |     ''' | ||||||
|  |     Inter-actor task context was cancelled by either a call to | ||||||
|  |     ``Portal.cancel_actor()`` or ``Context.cancel()``. | ||||||
|  | 
 | ||||||
|  |     ''' | ||||||
|  |     @property | ||||||
|  |     def canceller(self) -> tuple[str, str] | None: | ||||||
|  |         return self.msgdata.get('canceller') | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| class TransportClosed(trio.ClosedResourceError): | class TransportClosed(trio.ClosedResourceError): | ||||||
|     "Underlying channel transport was closed prior to use" |     "Underlying channel transport was closed prior to use" | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class ContextCancelled(RemoteActorError): |  | ||||||
|     "Inter-actor task context cancelled itself on the callee side." |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| class NoResult(RuntimeError): | class NoResult(RuntimeError): | ||||||
|     "No final result is expected for this actor" |     "No final result is expected for this actor" | ||||||
| 
 | 
 | ||||||
|  | @ -108,13 +119,17 @@ def pack_error( | ||||||
|     else: |     else: | ||||||
|         tb_str = traceback.format_exc() |         tb_str = traceback.format_exc() | ||||||
| 
 | 
 | ||||||
|     return { |     error_msg = { | ||||||
|         'error': { |         'tb_str': tb_str, | ||||||
|             'tb_str': tb_str, |         'type_str': type(exc).__name__, | ||||||
|             'type_str': type(exc).__name__, |         'src_actor_uid': current_actor().uid, | ||||||
|         } |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     if isinstance(exc, ContextCancelled): | ||||||
|  |         error_msg.update(exc.msgdata) | ||||||
|  | 
 | ||||||
|  |     return {'error': error_msg} | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| def unpack_error( | def unpack_error( | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue