Improved handling of invalid responses; Handle seq[byte] results such as `eth_getCode`
This commit is contained in:
parent
8c1a8ef8d9
commit
244254632b
|
@ -1,8 +1,12 @@
|
||||||
import tables, json, macros
|
import
|
||||||
import chronos
|
tables, json, macros,
|
||||||
|
chronos,
|
||||||
|
jsonmarshal, errors
|
||||||
|
|
||||||
from strutils import toLowerAscii
|
from strutils import toLowerAscii
|
||||||
import jsonmarshal
|
|
||||||
export chronos
|
export
|
||||||
|
chronos
|
||||||
|
|
||||||
type
|
type
|
||||||
ClientId* = int64
|
ClientId* = int64
|
||||||
|
@ -60,7 +64,8 @@ proc processMessage*(self: RpcClient, line: string) {.gcsafe.} =
|
||||||
if "id" in node:
|
if "id" in node:
|
||||||
let id = checkGet(node, "id", JInt)
|
let id = checkGet(node, "id", JInt)
|
||||||
|
|
||||||
if not self.awaiting.hasKey(id):
|
var requestFut: Future[Response]
|
||||||
|
if not self.awaiting.pop(id, requestFut):
|
||||||
raise newException(ValueError,
|
raise newException(ValueError,
|
||||||
"Cannot find message id \"" & $node["id"].getInt & "\"")
|
"Cannot find message id \"" & $node["id"].getInt & "\"")
|
||||||
|
|
||||||
|
@ -73,12 +78,12 @@ proc processMessage*(self: RpcClient, line: string) {.gcsafe.} =
|
||||||
if errorNode.isNil or errorNode.kind == JNull:
|
if errorNode.isNil or errorNode.kind == JNull:
|
||||||
var res = node{"result"}
|
var res = node{"result"}
|
||||||
if not res.isNil:
|
if not res.isNil:
|
||||||
self.awaiting[id].complete((false, res))
|
requestFut.complete((false, res))
|
||||||
self.awaiting.del(id)
|
|
||||||
# TODO: actions on unable find result node
|
|
||||||
else:
|
else:
|
||||||
self.awaiting[id].fail(newException(ValueError, $errorNode))
|
requestFut.fail(newException(InvalidResponse, "Missing `result` field"))
|
||||||
self.awaiting.del(id)
|
else:
|
||||||
|
requestFut.fail(newException(ValueError, $errorNode))
|
||||||
|
|
||||||
elif "method" in node:
|
elif "method" in node:
|
||||||
# This could be subscription notification
|
# This could be subscription notification
|
||||||
let name = node["method"].getStr()
|
let name = node["method"].getStr()
|
||||||
|
@ -175,9 +180,9 @@ proc createRpcFromSig*(clientType, rpcDecl: NimNode): NimNode =
|
||||||
callBody.add(jsonToNim(procRes, returnType, jsonRpcResult, "result"))
|
callBody.add(jsonToNim(procRes, returnType, jsonRpcResult, "result"))
|
||||||
else:
|
else:
|
||||||
# native json expected so no work
|
# native json expected so no work
|
||||||
callBody.add(quote do:
|
callBody.add quote do:
|
||||||
`procRes` = `rpcResult`.result
|
`procRes` = `rpcResult`.result
|
||||||
)
|
|
||||||
when defined(nimDumpRpcs):
|
when defined(nimDumpRpcs):
|
||||||
echo pathStr, ":\n", result.repr
|
echo pathStr, ":\n", result.repr
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
type
|
||||||
|
JsonRpcError* = object of CatchableError
|
||||||
|
## Base type of all nim-json-rpc errors
|
||||||
|
|
||||||
|
ErrorResponse* = object of JsonRpcError
|
||||||
|
## raised when the server responded with an error
|
||||||
|
|
||||||
|
InvalidResponse* = object of JsonRpcError
|
||||||
|
## raised when the server response violates the JSON-RPC protocol
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
import macros, json, options, typetraits
|
import
|
||||||
|
macros, json, options, typetraits,
|
||||||
|
stew/byteutils
|
||||||
|
|
||||||
proc expect*(actual, expected: JsonNodeKind, argName: string) =
|
proc expect*(actual, expected: JsonNodeKind, argName: string) =
|
||||||
if actual != expected: raise newException(ValueError, "Parameter [" & argName & "] expected " & $expected & " but got " & $actual)
|
if actual != expected: raise newException(ValueError, "Parameter [" & argName & "] expected " & $expected & " but got " & $actual)
|
||||||
|
@ -111,6 +113,11 @@ proc fromJson*(n: JsonNode, argName: string, result: var string) =
|
||||||
result = n.getStr()
|
result = n.getStr()
|
||||||
|
|
||||||
proc fromJson*[T](n: JsonNode, argName: string, result: var seq[T]) =
|
proc fromJson*[T](n: JsonNode, argName: string, result: var seq[T]) =
|
||||||
|
when T is byte:
|
||||||
|
if n.kind == JString:
|
||||||
|
result = hexToSeqByte n.getStr()
|
||||||
|
return
|
||||||
|
|
||||||
n.kind.expect(JArray, argName)
|
n.kind.expect(JArray, argName)
|
||||||
result = newSeq[T](n.len)
|
result = newSeq[T](n.len)
|
||||||
for i in 0 ..< n.len:
|
for i in 0 ..< n.len:
|
||||||
|
|
Loading…
Reference in New Issue