84 lines
2.6 KiB
Nim
Raw Normal View History

import std/strutils
import pkg/stew/byteutils
import ../../basics
import ../../errors
import ../../provider
import ./conversions
export errors
{.push raises:[].}
type JsonRpcProviderError* = object of ProviderError
func extractErrorData(json: JsonNode): ?seq[byte] =
if json.kind == JObject:
if "message" in json and "data" in json:
let message = json{"message"}.getStr()
let hex = json{"data"}.getStr()
if "reverted" in message and hex.startsWith("0x"):
if data =? hexToSeqByte(hex).catch:
return some data
for key in json.keys:
if data =? extractErrorData(json{key}):
return some data
func new*(_: type JsonRpcProviderError, json: JsonNode): ref JsonRpcProviderError =
let error = (ref JsonRpcProviderError)()
if "message" in json:
error.msg = json{"message"}.getStr
error.data = extractErrorData(json)
error
proc raiseJsonRpcProviderError*(
error: ref CatchableError, message = error.msg) {.raises: [JsonRpcProviderError].} =
if json =? JsonNode.fromJson(error.msg):
raise JsonRpcProviderError.new(json)
else:
raise newException(JsonRpcProviderError, message)
proc underlyingErrorOf(e: ref Exception, T: type CatchableError): (ref CatchableError) =
if e of (ref T):
return (ref T)(e)
elif not e.parent.isNil:
return e.parent.underlyingErrorOf T
else:
return nil
template convertError*(body) =
try:
try:
body
# Inspect SubscriptionErrors and re-raise underlying JsonRpcErrors so that
# exception inspection and resolution only needs to happen once. All
# CatchableErrors that occur in the Subscription module are converted to
# SubscriptionError, with the original error preserved as the exception's
# parent.
except SubscriptionError, SignerError:
let e = getCurrentException()
let parent = e.underlyingErrorOf(JsonRpcError)
if not parent.isNil:
raise parent
except CancelledError as error:
raise error
except RpcPostError as error:
raiseNetworkError(error)
except FailedHttpResponse as error:
raiseNetworkError(error)
except ErrorResponse as error:
if error.status == 429:
raise newException(RequestLimitError, error.msg, error)
elif error.status == 408:
raise newException(RequestTimeoutError, error.msg, error)
else:
raiseJsonRpcProviderError(error)
except JsonRpcError as error:
var message = error.msg
if jsn =? JsonNode.fromJson(message):
if "message" in jsn:
message = jsn{"message"}.getStr
raiseJsonRpcProviderError(error, message)
except CatchableError as error:
raiseJsonRpcProviderError(error)