From 70e50780c333e2947c52856b30eed88979339002 Mon Sep 17 00:00:00 2001
From: Victor Shyba <victor.shyba@gmail.com>
Date: Wed, 2 Sep 2020 14:33:36 -0300
Subject: [PATCH 1/7] dropdb ignores already dropped db

---
 Makefile | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Makefile b/Makefile
index 8cbbe02d4..38b457ee8 100644
--- a/Makefile
+++ b/Makefile
@@ -12,7 +12,7 @@ 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 \

From 7c5211d4204f84c03ed3b168cc4e9e92d2bd2e17 Mon Sep 17 00:00:00 2001
From: Victor Shyba <victor.shyba@gmail.com>
Date: Wed, 2 Sep 2020 14:34:00 -0300
Subject: [PATCH 2/7] fix lbrycrdd url

---
 lbry/blockchain/lbrycrd.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

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'
 )
 
 

From bc678f21466a42ffc16b7dab30a2fcc763144351 Mon Sep 17 00:00:00 2001
From: Victor Shyba <victor.shyba@gmail.com>
Date: Wed, 2 Sep 2020 18:49:41 -0300
Subject: [PATCH 3/7] session close is async, fix annoying error message

---
 lbry/service/api.py | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

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):

From 9b15799c72a6b12f1cd996f92197d04610cff7a0 Mon Sep 17 00:00:00 2001
From: Victor Shyba <victor.shyba@gmail.com>
Date: Wed, 2 Sep 2020 18:50:22 -0300
Subject: [PATCH 4/7] makefile default to match the number of CPUs and not
 arbitrary 28

---
 Makefile | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Makefile b/Makefile
index 38b457ee8..dbc6b9312 100644
--- a/Makefile
+++ b/Makefile
@@ -15,6 +15,6 @@ start:
 	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

From 6bbfb45de7faa4d898d79d8a211a7e7db17b52ac Mon Sep 17 00:00:00 2001
From: Victor Shyba <victor.shyba@gmail.com>
Date: Wed, 2 Sep 2020 20:38:30 -0300
Subject: [PATCH 5/7] return errors when websocket req fails

---
 lbry/service/daemon.py | 19 +++++++++++++------
 1 file changed, 13 insertions(+), 6 deletions(-)

diff --git a/lbry/service/daemon.py b/lbry/service/daemon.py
index a0a40bef8..b41b81543 100644
--- a/lbry/service/daemon.py
+++ b/lbry/service/daemon.py
@@ -152,12 +152,19 @@ 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:
+                import traceback
+                traceback.print_exc()
+                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):

From e1b55f017b3f902231c8ecead88f2bc73ed830d8 Mon Sep 17 00:00:00 2001
From: Victor Shyba <victor.shyba@gmail.com>
Date: Thu, 3 Sep 2020 13:55:31 -0300
Subject: [PATCH 6/7] remove traceback usage, add test

---
 lbry/cli.py                              |  5 +++--
 lbry/service/daemon.py                   |  2 --
 tests/integration/service/test_daemon.py | 13 +++++++++++++
 3 files changed, 16 insertions(+), 4 deletions(-)

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/daemon.py b/lbry/service/daemon.py
index b41b81543..a3b4e5a07 100644
--- a/lbry/service/daemon.py
+++ b/lbry/service/daemon.py
@@ -160,8 +160,6 @@ class Daemon:
                     'result': encoded_result
                 })
             except Exception as e:
-                import traceback
-                traceback.print_exc()
                 log.exception("RPC error")
                 await web_socket.send_json({'id': msg.get('id', ''), 'result': "unexpected error: " + str(e)})
                 raise e
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'"
+        )

From 1c79daaafcda6bda1bc7ec775436b1721c5bd2bb Mon Sep 17 00:00:00 2001
From: Victor Shyba <victor.shyba@gmail.com>
Date: Fri, 4 Sep 2020 00:11:18 -0300
Subject: [PATCH 7/7] linter: ignore raise-missing-from

---
 setup.cfg | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

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