@@ -34,10 +34,24 @@ extension APIRequest {
3434 }
3535 }
3636
37+ if let error = ( try ? JSONDecoder ( ) . decode ( JsonRpcErrorObject . self, from: data) ) ? . error {
38+ guard let parsedErrorCode = error. parsedErrorCode else {
39+ throw Web3Error . nodeError ( desc: " \( error. message) \n Error code: \( error. code) " )
40+ }
41+ let description = " \( parsedErrorCode. errorName) . Error code: \( error. code) . \( error. message) "
42+ switch parsedErrorCode {
43+ case . parseError, . invalidParams:
44+ throw Web3Error . inputError ( desc: description)
45+ case . methodNotFound, . invalidRequest:
46+ throw Web3Error . processingError ( desc: description)
47+ case . internalError, . serverError:
48+ throw Web3Error . nodeError ( desc: description)
49+ }
50+ }
51+
3752 /// This bit of code is purposed to work with literal types that comes in ``Response`` in hexString type.
3853 /// Currently it's just `Data` and any kind of Integers `(U)Int`, `Big(U)Int`.
39- if Result . self == Data . self || Result . self == UInt . self || Result . self == Int . self || Result . self == BigInt . self || Result . self == BigUInt . self {
40- guard let LiteralType = Result . self as? LiteralInitiableFromString . Type else { throw Web3Error . typeError }
54+ if let LiteralType = Result . self as? LiteralInitiableFromString . Type {
4155 guard let responseAsString = try ? JSONDecoder ( ) . decode ( APIResponse< String> . self , from: data) else { throw Web3Error . dataError }
4256 guard let literalValue = LiteralType . init ( from: responseAsString. result) else { throw Web3Error . dataError }
4357 /// `literalValue` conforms `LiteralInitiableFromString`, that conforming to an `APIResponseType` type, so it's never fails.
@@ -47,3 +61,76 @@ extension APIRequest {
4761 return try JSONDecoder ( ) . decode ( APIResponse< Result> . self , from: data)
4862 }
4963}
64+
65+ /// JSON RPC Error object. See official specification https://www.jsonrpc.org/specification#error_object
66+ fileprivate struct JsonRpcErrorObject : Decodable {
67+ public let error : RpcError ?
68+
69+ class RpcError : Decodable {
70+ let message : String
71+ let code : Int
72+ var parsedErrorCode : JsonRpcErrorCode ? {
73+ JsonRpcErrorCode . from ( code)
74+ }
75+ }
76+ }
77+
78+ /// For error codes specification see chapter `5.1 Error object`
79+ /// https://www.jsonrpc.org/specification#error_object
80+ fileprivate enum JsonRpcErrorCode {
81+ /// -32700
82+ /// Invalid JSON was received by the server. An error occurred on the server while parsing the JSON
83+ case parseError
84+ /// -32600
85+ /// The JSON sent is not a valid Request object.
86+ case invalidRequest
87+ /// -32601
88+ /// The method does not exist / is not available.
89+ case methodNotFound
90+ /// -32602
91+ /// Invalid method parameter(s).
92+ case invalidParams
93+ /// -32603
94+ /// Internal JSON-RPC error.
95+ case internalError
96+ /// Values in range of -32000 to -32099
97+ /// Reserved for implementation-defined server-errors.
98+ case serverError( Int )
99+
100+ var errorName : String {
101+ switch self {
102+ case . parseError:
103+ return " Parsing error "
104+ case . invalidRequest:
105+ return " Invalid request "
106+ case . methodNotFound:
107+ return " Method not found "
108+ case . invalidParams:
109+ return " Invalid parameters "
110+ case . internalError:
111+ return " Internal error "
112+ case . serverError( _) :
113+ return " Server error "
114+ }
115+ }
116+
117+ static func from( _ code: Int ) -> JsonRpcErrorCode ? {
118+ switch code {
119+ case - 32700 :
120+ return . parseError
121+ case - 32600 :
122+ return . invalidRequest
123+ case - 32601 :
124+ return . methodNotFound
125+ case - 32602 :
126+ return . invalidParams
127+ case - 32603 :
128+ return . internalError
129+ default :
130+ if ( - 32000 ) ... ( - 32099 ) ~= code {
131+ return . serverError( code)
132+ }
133+ return nil
134+ }
135+ }
136+ }
0 commit comments