Skip to content

Commit f8b1ebc

Browse files
committed
Merge #186: handle non-standard RPC responses
cd81db6 handle non-standard RPC responses (Dmitry Petukhov) Pull request description: Sometimes there is a need to issue RPC commands to the services that just pretend to be bitcoind, and are emulating some of its commands. These services might not follow the same protocol for error reporting as bitcoind does. An example of such service would be feesim (https://github.com/bitcoinfees/feesim, Model-based Bitcoin fee estimation) With these changes, we can handle non-standard error responses gracefully. Top commit has no ACKs. Tree-SHA512: 7cadfeee8bb70b4815b5d19385186ad55dca8d1c7c1448d9d55b58563552cf3b6d2c0fe8723855ff1751a5b5c396e904e2aa368ad42bc08a17b6360197317e82
2 parents e23c65b + cd81db6 commit f8b1ebc

File tree

1 file changed

+16
-4
lines changed

1 file changed

+16
-4
lines changed

bitcoin/rpc.py

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -231,8 +231,13 @@ def _call(self, service_name, *args):
231231
self.__conn.request('POST', self.__url.path, postdata, headers)
232232

233233
response = self._get_response()
234-
if response['error'] is not None:
235-
raise JSONRPCError(response['error'])
234+
err = response.get('error')
235+
if err is not None:
236+
if isinstance(err, dict):
237+
raise JSONRPCError(
238+
{'code': err.get('code', -345),
239+
'message': err.get('message', 'error message not specified')})
240+
raise JSONRPCError({'code': -344, 'message': str(err)})
236241
elif 'result' not in response:
237242
raise JSONRPCError({
238243
'code': -343, 'message': 'missing JSON-RPC result'})
@@ -260,8 +265,15 @@ def _get_response(self):
260265
raise JSONRPCError({
261266
'code': -342, 'message': 'missing HTTP response from server'})
262267

263-
return json.loads(http_response.read().decode('utf8'),
264-
parse_float=decimal.Decimal)
268+
rdata = http_response.read().decode('utf8')
269+
try:
270+
return json.loads(rdata, parse_float=decimal.Decimal)
271+
except Exception:
272+
raise JSONRPCError({
273+
'code': -342,
274+
'message': ('non-JSON HTTP response with \'%i %s\' from server: \'%.20s%s\''
275+
% (http_response.status, http_response.reason,
276+
rdata, '...' if len(rdata) > 20 else ''))})
265277

266278
def close(self):
267279
if self.__conn is not None:

0 commit comments

Comments
 (0)