[rpc] Add RPCError exception; handle it in poll_client

master
Daniel Edgecumbe 7 years ago
parent 7d45bd81a7
commit 2349c95e8e

@ -10,6 +10,7 @@ import asyncio
import view
from util import isoformatseconds
from rpc import RPCError
class BlockStore(object):

@ -54,8 +54,13 @@ async def poll_client(client, method, callback, sleeptime, params=None):
await asyncio.sleep(0.1)
while True:
j = await client.request(method, params=params)
await callback(method, j)
try:
d = await client.request(method, params=params)
except rpc.RPCError:
await asyncio.sleep(sleeptime)
continue
await callback(method, d)
await asyncio.sleep(sleeptime)
@ -89,17 +94,28 @@ def initialize():
return client, args.nosplash
def check_disablewallet(client):
def wallet_enabled(client):
""" Check if the wallet is enabled. """
async def check_getwalletinfo(client):
try:
await client.request("getwalletinfo")
except rpc.RPCError:
return False
try:
x.result()[0]["result"]["walletname"]
except (KeyError, TypeError):
return False
return True
# Ugly, a synchronous RPC request mechanism would be nice here.
x = asyncio.gather(client.request("getwalletinfo"))
check = asyncio.gather(check_getwalletinfo(client))
loop = asyncio.get_event_loop()
loop.run_until_complete(x)
loop.run_until_complete(check)
try:
x.result()[0]["result"]["walletname"]
except (KeyError, TypeError):
if check.result():
return True
return False
@ -210,7 +226,7 @@ def create_tasks(client, window, nosplash):
splashview.draw(nosplash),
]
if not check_disablewallet(client):
if wallet_enabled(client):
tasks.append(
poll_client(client, "getwalletinfo", headerview.on_walletinfo, 1.0)
)

@ -81,6 +81,11 @@ def get_auth_from_datadir(datadir):
return craft_auth_from_credentials(rpcuser, rpcpassword)
class RPCError(BaseException):
# TODO: include the error code, etc.
pass
class BitcoinRPCClient(object):
def __init__(self, url, auth):
self._url = url
@ -109,8 +114,32 @@ class BitcoinRPCClient(object):
async with session.post(self._url, headers=self._headers, data=req) as response:
return await response.text()
@staticmethod
async def _json_loads(j):
return json.loads(j)
async def request(self, method, params=None, ident=None, callback=None):
async with aiohttp.ClientSession() as session:
req = await self._craft_request(method, params, ident)
html = await self._fetch(session, req)
return json.loads(html)
j = await self._fetch(session, req)
d = await self._json_loads(j)
try:
error = d["error"]
except KeyError:
raise RPCError("RPC response seems malformed (no error field)")
if error is not None:
# TODO: pass the error up the stack; tweak RPCError
raise RPCError("RPC response returned error {}".format(error))
try:
result = d["result"]
except KeyError:
raise RPCError("RPC response seems malformed (no result field)")
if result is None:
# Is there a case in which a query can return None?
raise RPCError("RPC response returned a null result")
return d

Loading…
Cancel
Save