Propagate `trio.MultiError`s up the actor tree

`trio.MultiError` isn't an `Exception` (derived instead from
`BaseException`) so we have to specially catch it in the task
invocation machinery and ship it upwards (like regular errors)
since nurseries running in sub-actors can raise them.
more_thorough_super_tests
Tyler Goodlet 2019-10-28 00:47:06 -04:00
parent d406383cd3
commit 95e8f3d306
1 changed files with 5 additions and 4 deletions

View File

@ -118,7 +118,7 @@ async def _invoke(
with cancel_scope as cs: with cancel_scope as cs:
task_status.started(cs) task_status.started(cs)
await chan.send({'return': await coro, 'cid': cid}) await chan.send({'return': await coro, 'cid': cid})
except Exception as err: except (Exception, trio.MultiError) as err:
# always ship errors back to caller # always ship errors back to caller
log.exception("Actor errored:") log.exception("Actor errored:")
err_msg = pack_error(err) err_msg = pack_error(err)
@ -352,7 +352,8 @@ class Actor:
return cid, recv_chan return cid, recv_chan
async def _process_messages( async def _process_messages(
self, chan: Channel, self,
chan: Channel,
treat_as_gen: bool = False, treat_as_gen: bool = False,
shield: bool = False, shield: bool = False,
task_status=trio.TASK_STATUS_IGNORED, task_status=trio.TASK_STATUS_IGNORED,
@ -461,7 +462,7 @@ class Actor:
except trio.ClosedResourceError: except trio.ClosedResourceError:
log.error(f"{chan} form {chan.uid} broke") log.error(f"{chan} form {chan.uid} broke")
except Exception as err: except (Exception, trio.MultiError) as err:
# ship any "internal" exception (i.e. one from internal machinery # ship any "internal" exception (i.e. one from internal machinery
# not from an rpc task) to parent # not from an rpc task) to parent
log.exception("Actor errored:") log.exception("Actor errored:")
@ -472,7 +473,7 @@ class Actor:
# above to trigger an error at consuming portal "checkpoints" # above to trigger an error at consuming portal "checkpoints"
except trio.Cancelled: except trio.Cancelled:
# debugging only # debugging only
log.debug("Msg loop was cancelled") log.debug(f"Msg loop was cancelled for {chan}")
raise raise
finally: finally:
log.debug( log.debug(