Add a specially handled `ContextCancelled` error
							parent
							
								
									3999849b03
								
							
						
					
					
						commit
						eb3662f981
					
				|  | @ -1,7 +1,7 @@ | ||||||
| """ | """ | ||||||
| Our classy exception set. | Our classy exception set. | ||||||
| """ | """ | ||||||
| from typing import Dict, Any | from typing import Dict, Any, Optional | ||||||
| import importlib | import importlib | ||||||
| import builtins | import builtins | ||||||
| import traceback | import traceback | ||||||
|  | @ -15,17 +15,16 @@ _this_mod = importlib.import_module(__name__) | ||||||
| class RemoteActorError(Exception): | class RemoteActorError(Exception): | ||||||
|     # TODO: local recontruction of remote exception deats |     # TODO: local recontruction of remote exception deats | ||||||
|     "Remote actor exception bundled locally" |     "Remote actor exception bundled locally" | ||||||
|     def __init__(self, message, type_str, **msgdata) -> None: |     def __init__( | ||||||
|         super().__init__(message) |         self, | ||||||
|         for ns in [builtins, _this_mod, trio]: |         message: str, | ||||||
|             try: |         suberror_type: Optional[Exception] = None, | ||||||
|                 self.type = getattr(ns, type_str) |         **msgdata | ||||||
|                 break |  | ||||||
|             except AttributeError: |  | ||||||
|                 continue |  | ||||||
|         else: |  | ||||||
|             self.type = Exception |  | ||||||
| 
 | 
 | ||||||
|  |     ) -> None: | ||||||
|  |         super().__init__(message) | ||||||
|  | 
 | ||||||
|  |         self.type = suberror_type | ||||||
|         self.msgdata = msgdata |         self.msgdata = msgdata | ||||||
| 
 | 
 | ||||||
|     # TODO: a trio.MultiError.catch like context manager |     # TODO: a trio.MultiError.catch like context manager | ||||||
|  | @ -41,6 +40,9 @@ class InternalActorError(RemoteActorError): | ||||||
| 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" | ||||||
|  | @ -77,12 +79,35 @@ def unpack_error( | ||||||
|     into a local ``RemoteActorError``. |     into a local ``RemoteActorError``. | ||||||
| 
 | 
 | ||||||
|     """ |     """ | ||||||
|     tb_str = msg['error'].get('tb_str', '') |     error = msg['error'] | ||||||
|     return err_type( | 
 | ||||||
|         f"{chan.uid}\n" + tb_str, |     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'], |         **msg['error'], | ||||||
|     ) |     ) | ||||||
| 
 | 
 | ||||||
|  |     return exc | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| def is_multi_cancelled(exc: BaseException) -> bool: | def is_multi_cancelled(exc: BaseException) -> bool: | ||||||
|     """Predicate to determine if a ``trio.MultiError`` contains only |     """Predicate to determine if a ``trio.MultiError`` contains only | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue