diff options
| author | Richard Henderson <richard.henderson@linaro.org> | 2021-11-17 07:41:08 +0100 |
|---|---|---|
| committer | Richard Henderson <richard.henderson@linaro.org> | 2021-11-17 07:41:08 +0100 |
| commit | 8d5fcb1990bc64b62c0bc12121fe510940be5664 (patch) | |
| tree | eee77ac188895efcd9b16dc07ae94ca68b386bd9 /python/qemu | |
| parent | 67f9968ce3f0847ffddb6ee2837a3641acd92abf (diff) | |
| parent | c398a241ec4138e0b995a0215dea84ca93b0384f (diff) | |
| download | focaccia-qemu-8d5fcb1990bc64b62c0bc12121fe510940be5664.tar.gz focaccia-qemu-8d5fcb1990bc64b62c0bc12121fe510940be5664.zip | |
Merge tag 'python-pull-request' of https://gitlab.com/jsnow/qemu into staging
Pull request # gpg: Signature made Wed 17 Nov 2021 01:33:06 AM CET # gpg: using RSA key F9B7ABDBBCACDF95BE76CBD07DEF8106AAFC390E # gpg: Good signature from "John Snow (John Huston) <jsnow@redhat.com>" [full] * tag 'python-pull-request' of https://gitlab.com/jsnow/qemu: scripts/device-crash-test: hide tracebacks for QMP connect errors scripts/device-crash-test: don't emit AQMP connection errors to stdout scripts/device-crash-test: simplify Exception handling python/aqmp: fix ConnectError string method python/aqmp: Fix disconnect during capabilities negotiation Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Diffstat (limited to 'python/qemu')
| -rw-r--r-- | python/qemu/aqmp/protocol.py | 24 |
1 files changed, 18 insertions, 6 deletions
diff --git a/python/qemu/aqmp/protocol.py b/python/qemu/aqmp/protocol.py index ae1df24026..5190b33b13 100644 --- a/python/qemu/aqmp/protocol.py +++ b/python/qemu/aqmp/protocol.py @@ -79,7 +79,11 @@ class ConnectError(AQMPError): self.exc: Exception = exc def __str__(self) -> str: - return f"{self.error_message}: {self.exc!s}" + cause = str(self.exc) + if not cause: + # If there's no error string, use the exception name. + cause = exception_summary(self.exc) + return f"{self.error_message}: {cause}" class StateError(AQMPError): @@ -623,13 +627,21 @@ class AsyncProtocol(Generic[T]): def _done(task: Optional['asyncio.Future[Any]']) -> bool: return task is not None and task.done() - # NB: We can't rely on _bh_tasks being done() here, it may not - # yet have had a chance to run and gather itself. + # Are we already in an error pathway? If either of the tasks are + # already done, or if we have no tasks but a reader/writer; we + # must be. + # + # NB: We can't use _bh_tasks to check for premature task + # completion, because it may not yet have had a chance to run + # and gather itself. tasks = tuple(filter(None, (self._writer_task, self._reader_task))) error_pathway = _done(self._reader_task) or _done(self._writer_task) + if not tasks: + error_pathway |= bool(self._reader) or bool(self._writer) try: - # Try to flush the writer, if possible: + # Try to flush the writer, if possible. + # This *may* cause an error and force us over into the error path. if not error_pathway: await self._bh_flush_writer() except BaseException as err: @@ -639,7 +651,7 @@ class AsyncProtocol(Generic[T]): self.logger.debug("%s:\n%s\n", emsg, pretty_traceback()) raise finally: - # Cancel any still-running tasks: + # Cancel any still-running tasks (Won't raise): if self._writer_task is not None and not self._writer_task.done(): self.logger.debug("Cancelling writer task.") self._writer_task.cancel() @@ -652,7 +664,7 @@ class AsyncProtocol(Generic[T]): self.logger.debug("Waiting for tasks to complete ...") await asyncio.wait(tasks) - # Lastly, close the stream itself. (May raise): + # Lastly, close the stream itself. (*May raise*!): await self._bh_close_stream(error_pathway) self.logger.debug("Disconnected.") |