diff --git a/Makefile b/Makefile index 8cbbe02d4..dbc6b9312 100644 --- a/Makefile +++ b/Makefile @@ -12,9 +12,9 @@ idea: cp -r scripts/idea/* .idea start: - dropdb lbry + dropdb lbry --if-exists createdb lbry lbrynet start --full-node \ - --db-url=postgresql:///lbry --workers=28 --console=advanced --no-spv-address-filters \ + --db-url=postgresql:///lbry --workers=0 --console=advanced --no-spv-address-filters \ --lbrycrd-rpc-user=lbry --lbrycrd-rpc-pass=somethingelse \ --lbrycrd-dir=${HOME}/.lbrycrd --data-dir=/tmp/tmp-lbrynet diff --git a/lbry/blockchain/lbrycrd.py b/lbry/blockchain/lbrycrd.py index 086087493..441f8f506 100644 --- a/lbry/blockchain/lbrycrd.py +++ b/lbry/blockchain/lbrycrd.py @@ -24,7 +24,7 @@ from .ledger import Ledger, RegTestLedger log = logging.getLogger(__name__) DOWNLOAD_URL = ( - 'https://github.com/lbryio/lbrycrd/releases/download/v0.17.4.5/lbrycrd-linux-1745.zip' + 'https://github.com/lbryio/lbrycrd/releases/download/v0.17.4.6/lbrycrd-linux-1746.zip' ) diff --git a/lbry/cli.py b/lbry/cli.py index 4a2b3390d..fcb9e8947 100644 --- a/lbry/cli.py +++ b/lbry/cli.py @@ -176,9 +176,10 @@ def ensure_directory_exists(path: str): async def execute_command(conf, method, params): client = Client(f"http://{conf.api}/ws") await client.connect() - resp = await client.send(method, **params) - print(await resp.first) + resp = await (await client.send(method, **params)).first + print(resp) await client.disconnect() + return resp def normalize_value(x, key=None): diff --git a/lbry/service/api.py b/lbry/service/api.py index f7401b4e8..2b0bcdb27 100644 --- a/lbry/service/api.py +++ b/lbry/service/api.py @@ -3493,8 +3493,8 @@ class Client(API): self.ws = await self.session.ws_connect(self.url) self.receive_messages_task = asyncio.create_task(self.receive_messages()) - def disconnect(self): - self.session.close() + async def disconnect(self): + await self.session.close() self.receive_messages_task.cancel() async def receive_messages(self): diff --git a/lbry/service/daemon.py b/lbry/service/daemon.py index a0a40bef8..a3b4e5a07 100644 --- a/lbry/service/daemon.py +++ b/lbry/service/daemon.py @@ -152,12 +152,17 @@ class Daemon: else: params = msg.get('params', {}) method = getattr(self.api, msg['method']) - result = await method(**params) - encoded_result = jsonrpc_dumps_pretty(result, service=self.service) - await web_socket.send_json({ - 'id': msg.get('id', ''), - 'result': encoded_result - }) + try: + result = await method(**params) + encoded_result = jsonrpc_dumps_pretty(result, service=self.service) + await web_socket.send_json({ + 'id': msg.get('id', ''), + 'result': encoded_result + }) + except Exception as e: + log.exception("RPC error") + await web_socket.send_json({'id': msg.get('id', ''), 'result': "unexpected error: " + str(e)}) + raise e @staticmethod async def on_shutdown(app): diff --git a/setup.cfg b/setup.cfg index e9d810917..815da7a15 100644 --- a/setup.cfg +++ b/setup.cfg @@ -42,4 +42,5 @@ disable= too-many-instance-attributes, protected-access, unused-argument, - bad-continuation + bad-continuation, + raise-missing-from diff --git a/tests/integration/service/test_daemon.py b/tests/integration/service/test_daemon.py index 480b6f84d..5b0e34693 100644 --- a/tests/integration/service/test_daemon.py +++ b/tests/integration/service/test_daemon.py @@ -6,8 +6,10 @@ from threading import Thread from unittest import TestCase from lbry import Daemon, FullNode +from lbry.cli import execute_command from lbry.console import Console from lbry.blockchain.lbrycrd import Lbrycrd +from lbry.testcase import CommandTestCase class TestShutdown(TestCase): @@ -33,3 +35,14 @@ class TestShutdown(TestCase): thread.start() daemon.run() + + +class WebSocketAPITestCase(CommandTestCase): + async def test_api_failure_over_websocket_doesnt_hang(self): + self.assertEqual( + await asyncio.wait_for( + execute_command(self.daemon.conf, 'resolve', {'crazyparameters': 'not there'}), + timeout=1 + ), + "unexpected error: resolve() got an unexpected keyword argument 'crazyparameters'" + )