@@ -34,10 +34,24 @@ extension APIRequest {
34
34
}
35
35
}
36
36
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
+
37
52
/// This bit of code is purposed to work with literal types that comes in ``Response`` in hexString type.
38
53
/// 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 {
41
55
guard let responseAsString = try ? JSONDecoder ( ) . decode ( APIResponse< String> . self , from: data) else { throw Web3Error . dataError }
42
56
guard let literalValue = LiteralType . init ( from: responseAsString. result) else { throw Web3Error . dataError }
43
57
/// `literalValue` conforms `LiteralInitiableFromString`, that conforming to an `APIResponseType` type, so it's never fails.
@@ -47,3 +61,76 @@ extension APIRequest {
47
61
return try JSONDecoder ( ) . decode ( APIResponse< Result> . self , from: data)
48
62
}
49
63
}
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