forked from goodboy/tractor
`._exceptions`: typing and error unpacking updates
Bump type annotations to 3.10+ style throughout module as well as fill out doc strings a bit. Inside `unpack_error()` pop any `error_dict: dict` and, - return `None` early if not found, - versus pass directly as `**error_dict` to the error constructor instead of a double field read.multihomed
parent
ab2664da70
commit
e4a6223256
|
@ -113,18 +113,24 @@ class AsyncioCancelled(Exception):
|
||||||
|
|
||||||
def pack_error(
|
def pack_error(
|
||||||
exc: BaseException,
|
exc: BaseException,
|
||||||
tb=None,
|
tb: str | None = None,
|
||||||
|
|
||||||
) -> dict[str, Any]:
|
) -> dict[str, dict]:
|
||||||
"""Create an "error message" for tranmission over
|
'''
|
||||||
a channel (aka the wire).
|
Create an "error message" encoded for wire transport via an IPC
|
||||||
"""
|
`Channel`; expected to be unpacked on the receiver side using
|
||||||
|
`unpack_error()` below.
|
||||||
|
|
||||||
|
'''
|
||||||
if tb:
|
if tb:
|
||||||
tb_str = ''.join(traceback.format_tb(tb))
|
tb_str = ''.join(traceback.format_tb(tb))
|
||||||
else:
|
else:
|
||||||
tb_str = traceback.format_exc()
|
tb_str = traceback.format_exc()
|
||||||
|
|
||||||
error_msg = {
|
error_msg: dict[
|
||||||
|
str,
|
||||||
|
str | tuple[str, str]
|
||||||
|
] = {
|
||||||
'tb_str': tb_str,
|
'tb_str': tb_str,
|
||||||
'type_str': type(exc).__name__,
|
'type_str': type(exc).__name__,
|
||||||
'src_actor_uid': current_actor().uid,
|
'src_actor_uid': current_actor().uid,
|
||||||
|
@ -142,18 +148,28 @@ def unpack_error(
|
||||||
chan=None,
|
chan=None,
|
||||||
err_type=RemoteActorError
|
err_type=RemoteActorError
|
||||||
|
|
||||||
) -> Exception:
|
) -> None | Exception:
|
||||||
'''
|
'''
|
||||||
Unpack an 'error' message from the wire
|
Unpack an 'error' message from the wire
|
||||||
into a local ``RemoteActorError``.
|
into a local `RemoteActorError` (subtype).
|
||||||
|
|
||||||
|
NOTE: this routine DOES not RAISE the embedded remote error,
|
||||||
|
which is the responsibilitiy of the caller.
|
||||||
|
|
||||||
'''
|
'''
|
||||||
__tracebackhide__ = True
|
__tracebackhide__: bool = True
|
||||||
error = msg['error']
|
|
||||||
|
|
||||||
tb_str = error.get('tb_str', '')
|
error_dict: dict[str, dict] | None
|
||||||
message = f'{chan.uid}\n' + tb_str
|
if (
|
||||||
type_name = error['type_str']
|
error_dict := msg.get('error')
|
||||||
|
) is None:
|
||||||
|
# no error field, nothing to unpack.
|
||||||
|
return None
|
||||||
|
|
||||||
|
# retrieve the remote error's msg encoded details
|
||||||
|
tb_str: str = error_dict.get('tb_str', '')
|
||||||
|
message: str = f'{chan.uid}\n' + tb_str
|
||||||
|
type_name: str = error_dict['type_str']
|
||||||
suberror_type: Type[BaseException] = Exception
|
suberror_type: Type[BaseException] = Exception
|
||||||
|
|
||||||
if type_name == 'ContextCancelled':
|
if type_name == 'ContextCancelled':
|
||||||
|
@ -167,18 +183,19 @@ def unpack_error(
|
||||||
eg,
|
eg,
|
||||||
trio,
|
trio,
|
||||||
]:
|
]:
|
||||||
try:
|
if suberror_type := getattr(
|
||||||
suberror_type = getattr(ns, type_name)
|
ns,
|
||||||
|
type_name,
|
||||||
|
False,
|
||||||
|
):
|
||||||
break
|
break
|
||||||
except AttributeError:
|
|
||||||
continue
|
|
||||||
|
|
||||||
exc = err_type(
|
exc = err_type(
|
||||||
message,
|
message,
|
||||||
suberror_type=suberror_type,
|
suberror_type=suberror_type,
|
||||||
|
|
||||||
# unpack other fields into error type init
|
# unpack other fields into error type init
|
||||||
**msg['error'],
|
**error_dict,
|
||||||
)
|
)
|
||||||
|
|
||||||
return exc
|
return exc
|
||||||
|
|
Loading…
Reference in New Issue