forked from goodboy/tractor
1
0
Fork 0

Use `Context._stream` in `_raise_from_unexpected_msg()`

Instead of expecting it to be passed in (as it was prior), when
determining if a `Stop` msg is a valid end-of-channel signal use the
`ctx._stream: MsgStream|None` attr which **must** be set by any stream
opening API; either of:
- `Context.open_stream()`
- `Portal.open_stream_from()`

Adjust the case block logic to match with fallthrough from any EoC to
a closed error if necessary. Change the `_type: str` to match the
failing IPC-prim name in the tail case we raise a `MessagingError`.

Other:
- move `.sender: tuple` uid attr up to `RemoteActorError` since `Error`
  optionally defines it as a field and for boxed `StreamOverrun`s (an
  ignore case we check for in the runtime during cancellation) we want
  it readable from the boxing rae.
- drop still unused `InternalActorError`.
runtime_to_msgspec
Tyler Goodlet 2024-04-24 12:31:05 -04:00
parent 5eb9144921
commit 18e97a8f9a
1 changed files with 49 additions and 58 deletions

View File

@ -532,7 +532,8 @@ class RemoteActorError(Exception):
self,
) -> BaseException:
'''
Unpack the inner-most source error from it's original IPC msg data.
Unpack the inner-most source error from it's original IPC
msg data.
We attempt to reconstruct (as best as we can) the original
`Exception` from as it would have been raised in the
@ -570,6 +571,14 @@ class RemoteActorError(Exception):
# # boxed_type=get_type_ref(..
# raise NotImplementedError
@property
def sender(self) -> tuple[str, str]|None:
if (
(msg := self._ipc_msg)
and (value := msg.sender)
):
return tuple(value)
class ContextCancelled(RemoteActorError):
'''
@ -734,20 +743,6 @@ class StreamOverrun(
handled by app code using `MsgStream.send()/.receive()`.
'''
@property
def sender(self) -> tuple[str, str] | None:
value = self._ipc_msg.sender
if value:
return tuple(value)
# class InternalActorError(RemoteActorError):
# '''
# Boxed (Remote) internal `tractor` error indicating failure of some
# primitive, machinery state or lowlevel task that should never
# occur.
# '''
class TransportClosed(trio.ClosedResourceError):
@ -945,7 +940,6 @@ def _raise_from_unexpected_msg(
log: StackLevelAdapter, # caller specific `log` obj
expect_msg: str = Yield,
stream: MsgStream | None = None,
# allow "deeper" tbs when debugging B^o
hide_tb: bool = True,
@ -987,6 +981,8 @@ def _raise_from_unexpected_msg(
) from src_err
# TODO: test that shows stream raising an expected error!!!
stream: MsgStream|None
_type: str = 'Context'
# raise the error message in a boxed exception type!
if isinstance(msg, Error):
@ -1003,12 +999,13 @@ def _raise_from_unexpected_msg(
# TODO: does it make more sense to pack
# the stream._eoc outside this in the calleer always?
# case Stop():
elif (
elif stream := ctx._stream:
_type: str = 'MsgStream'
if (
stream._eoc
or
isinstance(msg, Stop)
or (
stream
and stream._eoc
)
):
log.debug(
f'Context[{cid}] stream was stopped by remote side\n'
@ -1040,18 +1037,12 @@ def _raise_from_unexpected_msg(
ctx.maybe_raise()
raise eoc from src_err
if (
stream
and stream._closed
):
if stream._closed:
# TODO: our own error subtype?
raise trio.ClosedResourceError(
'This stream was closed'
)
raise trio.ClosedResourceError('This stream was closed')
# always re-raise the source error if no translation error case
# is activated above.
_type: str = 'Stream' if stream else 'Context'
raise MessagingError(
f"{_type} was expecting a {expect_msg} message"
" BUT received a non-error msg:\n"