From dabed6288ad0b4593872bd71117b2ebb4eee1ae4 Mon Sep 17 00:00:00 2001 From: Joshua Watt Date: Fri, 3 Nov 2023 08:26:28 -0600 Subject: [PATCH] bitbake: asyncrpc: Add InvokeError Adds support for Invocation Errors (that is, errors raised by the actual RPC call instead of at the protocol level) to propagate across the connection. If a server RPC call raises an InvokeError, it will be sent across the connection and then raised on the client side also. The connection is still terminated on this error. (Bitbake rev: 50ee68175e7cf20a32bfbb176db2c47d7859da04) Signed-off-by: Joshua Watt Signed-off-by: Richard Purdie --- bitbake/lib/bb/asyncrpc/__init__.py | 1 + bitbake/lib/bb/asyncrpc/client.py | 10 ++++++++-- bitbake/lib/bb/asyncrpc/exceptions.py | 4 ++++ bitbake/lib/bb/asyncrpc/serv.py | 11 +++++++++-- 4 files changed, 22 insertions(+), 4 deletions(-) diff --git a/bitbake/lib/bb/asyncrpc/__init__.py b/bitbake/lib/bb/asyncrpc/__init__.py index 9f677eac4c..a4371643d7 100644 --- a/bitbake/lib/bb/asyncrpc/__init__.py +++ b/bitbake/lib/bb/asyncrpc/__init__.py @@ -12,4 +12,5 @@ from .exceptions import ( ClientError, ServerError, ConnectionClosedError, + InvokeError, ) diff --git a/bitbake/lib/bb/asyncrpc/client.py b/bitbake/lib/bb/asyncrpc/client.py index 009085c306..d27dbf7121 100644 --- a/bitbake/lib/bb/asyncrpc/client.py +++ b/bitbake/lib/bb/asyncrpc/client.py @@ -11,7 +11,7 @@ import os import socket import sys from .connection import StreamConnection, WebsocketConnection, DEFAULT_MAX_CHUNK -from .exceptions import ConnectionClosedError +from .exceptions import ConnectionClosedError, InvokeError class AsyncClient(object): @@ -93,12 +93,18 @@ class AsyncClient(object): await self.close() count += 1 + def check_invoke_error(self, msg): + if isinstance(msg, dict) and "invoke-error" in msg: + raise InvokeError(msg["invoke-error"]["message"]) + async def invoke(self, msg): async def proc(): await self.socket.send_message(msg) return await self.socket.recv_message() - return await self._send_wrapper(proc) + result = await self._send_wrapper(proc) + self.check_invoke_error(result) + return result async def ping(self): return await self.invoke({"ping": {}}) diff --git a/bitbake/lib/bb/asyncrpc/exceptions.py b/bitbake/lib/bb/asyncrpc/exceptions.py index a8942b4f0c..ae1043a38b 100644 --- a/bitbake/lib/bb/asyncrpc/exceptions.py +++ b/bitbake/lib/bb/asyncrpc/exceptions.py @@ -9,6 +9,10 @@ class ClientError(Exception): pass +class InvokeError(Exception): + pass + + class ServerError(Exception): pass diff --git a/bitbake/lib/bb/asyncrpc/serv.py b/bitbake/lib/bb/asyncrpc/serv.py index c99add4dd1..5fed1730df 100644 --- a/bitbake/lib/bb/asyncrpc/serv.py +++ b/bitbake/lib/bb/asyncrpc/serv.py @@ -14,7 +14,7 @@ import sys import multiprocessing import logging from .connection import StreamConnection, WebsocketConnection -from .exceptions import ClientError, ServerError, ConnectionClosedError +from .exceptions import ClientError, ServerError, ConnectionClosedError, InvokeError class ClientLoggerAdapter(logging.LoggerAdapter): @@ -76,7 +76,14 @@ class AsyncServerConnection(object): d = await self.socket.recv_message() if d is None: break - response = await self.dispatch_message(d) + try: + response = await self.dispatch_message(d) + except InvokeError as e: + await self.socket.send_message( + {"invoke-error": {"message": str(e)}} + ) + break + if response is not self.NO_RESPONSE: await self.socket.send_message(response)