-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathjsonrpcclient.js
More file actions
115 lines (95 loc) · 3.08 KB
/
jsonrpcclient.js
File metadata and controls
115 lines (95 loc) · 3.08 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
const defaultConfig = {
debug: false,
};
const defaultHeaders = {
'Accept': 'application/json',
'Content-Type': 'application/json',
};
export default class JsonRpcClient {
constructor({ endpoint = '/', headers = {}, config }) {
this.lastId = 0;
this.endpoint = endpoint;
this.config = Object.assign({}, defaultConfig, config);
this.headers = Object.assign({}, defaultHeaders, headers);
}
request(method, ...params) {
const id = this.lastId++;
const req = {
method: 'POST',
headers: this.headers,
body: JSON.stringify({
jsonrpc: '2.0',
id,
method,
params: Array.isArray(params) ? params : [params],
}),
};
if (this.config.debug === true) {
// eslint-disable-next-line no-console
console.log('Executing request', this.lastId, 'to', this.endpoint, ':', req);
}
return fetch(this.endpoint, req)
.then(res => checkStatus(res))
.then(res => parseJSON(res))
.then(res => checkError(res, req, this.config.debug))
.then(res => logResponse(res, this.config.debug));
}
}
function parseJSON(response) {
return response.json();
}
function checkStatus(response) {
// we assume 400 as valid code here because it's the default return code when sth has gone wrong,
// but then we have an error within the response, no?
if (response.status >= 200 && response.status <= 400) {
return response;
}
const error = new Error(response.statusText);
error.response = response;
throw error;
}
function checkError(data, req, debug = false) {
if (data.error) {
/* eslint-disable no-console */
if (debug === true && console && console.error) {
console.error(`Request ID ${data.id} failed: ${data.error}`);
} else if (debug === true && console && console.log) {
console.log(`Request ID ${data.id} failed: ${data.error}`);
}
/* eslint-enable no-console */
const error = new RpcError(data.error, req, data);
error.response = data;
throw error;
}
return data;
}
function logResponse(response, debug = false) {
if (debug === true) {
/* eslint-disable no-console */
console.log('Got response for id', response.id, 'with response', response.result);
console.log('Response message for request', response.id, ':', response.result.message);
/* eslint-enable no-console */
}
return response.result;
}
/**
* RpcError is a simple error wrapper holding the request and the response.
*/
export class RpcError extends Error {
constructor(message, request, response) {
super(message);
this.name = 'RpcError';
this.message = (message || '');
this.request = request;
this.response = response;
}
toString() {
return this.message;
}
getRequest() {
return this.request;
}
getResponse() {
return this.response;
}
}