forked from goodboy/tractor
Add a specially handled `ContextCancelled` error
parent
19a23fefa9
commit
e058506a00
tractor
|
@ -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
|
||||
|
@ -41,6 +40,9 @@ class InternalActorError(RemoteActorError):
|
|||
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 +79,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