forked from ruimarinho/bitcoin-core
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathparser.js
107 lines (84 loc) · 2.74 KB
/
parser.js
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
/**
* Module dependencies.
*/
import JSONBigInt from 'json-bigint';
import RpcError from './errors/rpc-error';
import _ from 'lodash';
/**
* JSONBigInt parser.
*/
const { parse } = JSONBigInt({ storeAsString: true, strict: true }); // eslint-disable-line new-cap
/**
* Get RPC response body result.
*/
function getRpcResult(body, { headers = false, response } = {}) {
if (body.error !== null) {
throw new RpcError(
_.get(body, 'error.code', -32603),
_.get(body, 'error.message', 'An error occurred while processing the RPC call to bitcoind')
);
}
// Defensive measure. This should not happen on a RPC call.
if (!_.has(body, 'result')) {
throw new RpcError(-32700, 'Missing `result` on the RPC call result');
}
if (headers) {
return [body.result, response.headers];
}
return body.result;
}
/**
* Export Parser class.
*/
export default class Parser {
constructor({ headers } = {}) {
this.headers = headers;
}
/**
* Parse rpc response.
*/
rpc([response, body]) {
// The RPC api returns a `text/html; charset=ISO-8859-1` encoded response with an empty string as the body
// when an error occurs.
if (typeof body === 'string' && response.headers['content-type'] !== 'application/json' && response.statusCode !== 200) {
throw new RpcError(response.statusCode, response.statusMessage, { body });
}
// Parsing the body with custom parser to support BigNumbers.
body = parse(body);
if (!Array.isArray(body)) {
return getRpcResult(body, { headers: this.headers, response });
}
// Batch response parsing where each response may or may not be successful.
const batch = body.map(response => {
try {
return getRpcResult(response, { headers: false, response });
} catch (e) {
return e;
}
});
if (this.headers) {
return [batch, response.headers];
}
return batch;
}
rest(extension, [response, body]) {
// The REST api returns a `text/plain` encoded response with the error line and the control
// characters \r\n. For readability and debuggability, the error message is set to this content.
// When requesting a binary response, the body will be returned as a Buffer representation of
// this error string.
if (response.headers['content-type'] !== 'application/json' && response.statusCode !== 200) {
if (body instanceof Buffer) {
body = body.toString('utf-8');
}
throw new RpcError(response.statusCode, body.replace('\r\n', ''), { body });
}
// Parsing the body with custom parser to support BigNumbers.
if (extension === 'json') {
body = parse(body);
}
if (this.headers) {
return [body, response.headers];
}
return body;
}
}