Add a specially handled `ContextCancelled` error
							parent
							
								
									1c7c9da99c
								
							
						
					
					
						commit
						fed927d00f
					
				|  | @ -1,7 +1,7 @@ | |||
| """ | ||||
| Our classy exception set. | ||||
| """ | ||||
| from typing import Dict, Any | ||||
| from typing import Dict, Any, Optional | ||||
| import importlib | ||||
| import builtins | ||||
| import traceback | ||||
|  | @ -15,17 +15,16 @@ _this_mod = importlib.import_module(__name__) | |||
| class RemoteActorError(Exception): | ||||
|     # TODO: local recontruction of remote exception deats | ||||
|     "Remote actor exception bundled locally" | ||||
|     def __init__(self, message, type_str, **msgdata) -> None: | ||||
|         super().__init__(message) | ||||
|         for ns in [builtins, _this_mod, trio]: | ||||
|             try: | ||||
|                 self.type = getattr(ns, type_str) | ||||
|                 break | ||||
|             except AttributeError: | ||||
|                 continue | ||||
|         else: | ||||
|             self.type = Exception | ||||
|     def __init__( | ||||
|         self, | ||||
|         message: str, | ||||
|         suberror_type: Optional[Exception] = None, | ||||
|         **msgdata | ||||
| 
 | ||||
|     ) -> None: | ||||
|         super().__init__(message) | ||||
| 
 | ||||
|         self.type = suberror_type | ||||
|         self.msgdata = msgdata | ||||
| 
 | ||||
|     # TODO: a trio.MultiError.catch like context manager | ||||
|  | @ -42,6 +41,10 @@ class TransportClosed(trio.ClosedResourceError): | |||
|     "Underlying channel transport was closed prior to use" | ||||
| 
 | ||||
| 
 | ||||
| class ContextCancelled(RemoteActorError): | ||||
|     "Inter-actor task context cancelled itself on the callee side." | ||||
| 
 | ||||
| 
 | ||||
| class NoResult(RuntimeError): | ||||
|     "No final result is expected for this actor" | ||||
| 
 | ||||
|  | @ -77,12 +80,35 @@ def unpack_error( | |||
|     into a local ``RemoteActorError``. | ||||
| 
 | ||||
|     """ | ||||
|     tb_str = msg['error'].get('tb_str', '') | ||||
|     return err_type( | ||||
|         f"{chan.uid}\n" + tb_str, | ||||
|     error = msg['error'] | ||||
| 
 | ||||
|     tb_str = error.get('tb_str', '') | ||||
|     message = f"{chan.uid}\n" + tb_str | ||||
|     type_name = error['type_str'] | ||||
|     suberror_type = Exception | ||||
| 
 | ||||
|     if type_name == 'ContextCancelled': | ||||
|         err_type = ContextCancelled | ||||
|         suberror_type = trio.Cancelled | ||||
| 
 | ||||
|     else:  # try to lookup a suitable local error type | ||||
|         for ns in [builtins, _this_mod, trio]: | ||||
|             try: | ||||
|                 suberror_type = getattr(ns, type_name) | ||||
|                 break | ||||
|             except AttributeError: | ||||
|                 continue | ||||
| 
 | ||||
|     exc = err_type( | ||||
|         message, | ||||
|         suberror_type=suberror_type, | ||||
| 
 | ||||
|         # unpack other fields into error type init | ||||
|         **msg['error'], | ||||
|     ) | ||||
| 
 | ||||
|     return exc | ||||
| 
 | ||||
| 
 | ||||
| def is_multi_cancelled(exc: BaseException) -> bool: | ||||
|     """Predicate to determine if a ``trio.MultiError`` contains only | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue