Browse Source

rpc.py: on_fail='raise', RPCFailure exception

MMGen 7 years ago
parent
commit
d457259fcf
1 changed files with 18 additions and 11 deletions
  1. 18 11
      mmgen/rpc.py

+ 18 - 11
mmgen/rpc.py

@@ -25,6 +25,8 @@ import httplib,base64,json
 from mmgen.common import *
 from decimal import Decimal
 
+class RPCFailure(Exception): pass
+
 class CoinDaemonRPCConnection(object):
 
 	def __init__(self,host=None,port=None,user=None,passwd=None,auth_cookie=None):
@@ -65,6 +67,7 @@ class CoinDaemonRPCConnection(object):
 	# kwargs are for local use and are not passed to server
 
 	# By default, dies with an error msg on all errors and exceptions
+	# on_fail is one of 'die' (default), 'return', 'silent', 'raise'
 	# With on_fail='return', returns 'rpcfail',(resp_object,(die_args))
 	def request(self,cmd,*args,**kwargs):
 
@@ -80,12 +83,16 @@ class CoinDaemonRPCConnection(object):
 		else:
 			p = {'method':cmd,'params':args,'id':1}
 
-		def die_maybe(*args):
+		def do_fail(*args):
 			if cf['on_fail'] in ('return','silent'):
 				return 'rpcfail',args
-			else:
-				try:    s = u'{}'.format(args[2])
-				except: s = repr(args[2])
+
+			try:    s = u'{}'.format(args[2])
+			except: s = repr(args[2])
+
+			if cf['on_fail'] == 'raise':
+				raise RPCFailure,s
+			elif cf['on_fail'] == 'die':
 				die(args[1],yellow(s))
 
 		dmsg('=== request() debug ===')
@@ -111,18 +118,18 @@ class CoinDaemonRPCConnection(object):
 			})
 		except Exception as e:
 			m = '{}\nUnable to connect to {} at {}:{}'
-			return die_maybe(None,2,m.format(e,g.proto.daemon_name,self.host,self.port))
+			return do_fail(None,2,m.format(e,g.proto.daemon_name,self.host,self.port))
 
 		try:
 			r = hc.getresponse() # returns HTTPResponse instance
 		except Exception:
 			m = 'Unable to connect to {} at {}:{} (but port is bound?)'
-			return die_maybe(None,2,m.format(g.proto.daemon_name,self.host,self.port))
+			return do_fail(None,2,m.format(g.proto.daemon_name,self.host,self.port))
 
 		dmsg('    RPC GETRESPONSE data ==> %s\n' % r.__dict__)
 
 		if r.status != 200:
-			if cf['on_fail'] != 'silent':
+			if cf['on_fail'] not in ('silent','raise'):
 				msg_r(yellow('{} RPC Error: '.format(g.proto.daemon_name.capitalize())))
 				msg(red('{} {}'.format(r.status,r.reason)))
 			e1 = r.read()
@@ -131,14 +138,14 @@ class CoinDaemonRPCConnection(object):
 				e2 = '{} (code {})'.format(e3['message'],e3['code'])
 			except:
 				e2 = str(e1)
-			return die_maybe(r,1,e2)
+			return do_fail(r,1,e2)
 
 		r2 = r.read()
 
 		dmsg('    RPC REPLY data ==> %s\n' % r2)
 
 		if not r2:
-			return die_maybe(r,2,'Error: empty reply')
+			return do_fail(r,2,'Error: empty reply')
 
 #		from decimal import Decimal
 		r3 = json.loads(r2.decode('utf8'), parse_float=Decimal)
@@ -146,10 +153,10 @@ class CoinDaemonRPCConnection(object):
 
 		for resp in r3 if cf['batch'] else [r3]:
 			if 'error' in resp and resp['error'] != None:
-				return die_maybe(r,1,'{} returned an error: {}'.format(
+				return do_fail(r,1,'{} returned an error: {}'.format(
 					g.proto.daemon_name.capitalize(),resp['error']))
 			elif 'result' not in resp:
-				return die_maybe(r,1, 'Missing JSON-RPC result\n' + repr(resps))
+				return do_fail(r,1, 'Missing JSON-RPC result\n' + repr(resps))
 			else:
 				ret.append(resp['result'])