@webex/http-core 2.59.3-next.1 → 2.59.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc.js +6 -6
- package/README.md +64 -64
- package/babel.config.js +3 -3
- package/dist/http-error-subtypes.js +57 -57
- package/dist/http-error-subtypes.js.map +1 -1
- package/dist/http-error.js +25 -25
- package/dist/http-error.js.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/interceptors/http-status.js +13 -13
- package/dist/interceptors/http-status.js.map +1 -1
- package/dist/lib/detect.js +6 -6
- package/dist/lib/detect.js.map +1 -1
- package/dist/lib/interceptor.js +34 -34
- package/dist/lib/interceptor.js.map +1 -1
- package/dist/lib/xhr.js +2 -2
- package/dist/lib/xhr.js.map +1 -1
- package/dist/progress-event.js +6 -6
- package/dist/progress-event.js.map +1 -1
- package/dist/request/index.js +11 -11
- package/dist/request/index.js.map +1 -1
- package/dist/request/request.js +14 -14
- package/dist/request/request.js.map +1 -1
- package/dist/request/request.shim.js +65 -65
- package/dist/request/request.shim.js.map +1 -1
- package/jest.config.js +3 -3
- package/package.json +17 -18
- package/process +1 -1
- package/src/http-error-subtypes.js +187 -187
- package/src/http-error.js +147 -147
- package/src/index.js +58 -58
- package/src/interceptors/http-status.js +63 -63
- package/src/lib/detect.js +33 -33
- package/src/lib/interceptor.js +95 -95
- package/src/lib/xhr.js +258 -258
- package/src/progress-event.js +37 -37
- package/src/request/index.js +62 -62
- package/src/request/request.js +109 -109
- package/src/request/request.shim.js +304 -304
- package/test/integration/spec/http-error.js +188 -188
- package/test/integration/spec/interceptor.js +71 -71
- package/test/integration/spec/progress-event.js +83 -83
- package/test/integration/spec/request.js +310 -310
- package/test/unit/spec/interceptors/http-status.js +49 -49
|
@@ -1,187 +1,187 @@
|
|
|
1
|
-
/*!
|
|
2
|
-
* Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* @param {Error} Base
|
|
7
|
-
* @returns {undefined}
|
|
8
|
-
*/
|
|
9
|
-
export default function makeSubTypes(Base) {
|
|
10
|
-
/**
|
|
11
|
-
* NetworkOrCORSError
|
|
12
|
-
*/
|
|
13
|
-
class NetworkOrCORSError extends Base {}
|
|
14
|
-
/**
|
|
15
|
-
* BadRequest
|
|
16
|
-
*/
|
|
17
|
-
class BadRequest extends Base {}
|
|
18
|
-
/**
|
|
19
|
-
* Unauthorized
|
|
20
|
-
*/
|
|
21
|
-
class Unauthorized extends BadRequest {}
|
|
22
|
-
/**
|
|
23
|
-
* PaymentRequired
|
|
24
|
-
*/
|
|
25
|
-
class PaymentRequired extends BadRequest {}
|
|
26
|
-
/**
|
|
27
|
-
* Forbidden
|
|
28
|
-
*/
|
|
29
|
-
class Forbidden extends BadRequest {}
|
|
30
|
-
/**
|
|
31
|
-
* NotFound
|
|
32
|
-
*/
|
|
33
|
-
class NotFound extends BadRequest {}
|
|
34
|
-
/**
|
|
35
|
-
* MethodNotAllowed
|
|
36
|
-
*/
|
|
37
|
-
class MethodNotAllowed extends BadRequest {}
|
|
38
|
-
/**
|
|
39
|
-
* NotAcceptable
|
|
40
|
-
*/
|
|
41
|
-
class NotAcceptable extends BadRequest {}
|
|
42
|
-
/**
|
|
43
|
-
* ProxyAuthenticationRequired
|
|
44
|
-
*/
|
|
45
|
-
class ProxyAuthenticationRequired extends BadRequest {}
|
|
46
|
-
/**
|
|
47
|
-
* RequestTimeout
|
|
48
|
-
*/
|
|
49
|
-
class RequestTimeout extends BadRequest {}
|
|
50
|
-
/**
|
|
51
|
-
* Conflict
|
|
52
|
-
*/
|
|
53
|
-
class Conflict extends BadRequest {}
|
|
54
|
-
/**
|
|
55
|
-
* Gone
|
|
56
|
-
*/
|
|
57
|
-
class Gone extends BadRequest {}
|
|
58
|
-
/**
|
|
59
|
-
* LengthRequired
|
|
60
|
-
*/
|
|
61
|
-
class LengthRequired extends BadRequest {}
|
|
62
|
-
/**
|
|
63
|
-
* PreconditionFailed
|
|
64
|
-
*/
|
|
65
|
-
class PreconditionFailed extends BadRequest {}
|
|
66
|
-
/**
|
|
67
|
-
* RequestEntityTooLarge
|
|
68
|
-
*/
|
|
69
|
-
class RequestEntityTooLarge extends BadRequest {}
|
|
70
|
-
/**
|
|
71
|
-
* RequestUriTooLong
|
|
72
|
-
*/
|
|
73
|
-
class RequestUriTooLong extends BadRequest {}
|
|
74
|
-
/**
|
|
75
|
-
* UnsupportedMediaType
|
|
76
|
-
*/
|
|
77
|
-
class UnsupportedMediaType extends BadRequest {}
|
|
78
|
-
/**
|
|
79
|
-
* RequestRangeNotSatisfiable
|
|
80
|
-
*/
|
|
81
|
-
class RequestRangeNotSatisfiable extends BadRequest {}
|
|
82
|
-
/**
|
|
83
|
-
* ExpectationFailed
|
|
84
|
-
*/
|
|
85
|
-
class ExpectationFailed extends BadRequest {}
|
|
86
|
-
/**
|
|
87
|
-
* TooManyRequests
|
|
88
|
-
*/
|
|
89
|
-
class TooManyRequests extends BadRequest {}
|
|
90
|
-
/**
|
|
91
|
-
* InternalServerError
|
|
92
|
-
*/
|
|
93
|
-
class InternalServerError extends Base {}
|
|
94
|
-
/**
|
|
95
|
-
* NotImplemented
|
|
96
|
-
*/
|
|
97
|
-
class NotImplemented extends InternalServerError {}
|
|
98
|
-
/**
|
|
99
|
-
* BadGateway
|
|
100
|
-
*/
|
|
101
|
-
class BadGateway extends InternalServerError {}
|
|
102
|
-
/**
|
|
103
|
-
* ServiceUnavailable
|
|
104
|
-
*/
|
|
105
|
-
class ServiceUnavailable extends InternalServerError {}
|
|
106
|
-
/**
|
|
107
|
-
* GatewayTimeout
|
|
108
|
-
*/
|
|
109
|
-
class GatewayTimeout extends InternalServerError {}
|
|
110
|
-
/**
|
|
111
|
-
* HttpVersionNotSupported
|
|
112
|
-
*/
|
|
113
|
-
class HttpVersionNotSupported extends InternalServerError {}
|
|
114
|
-
|
|
115
|
-
Object.assign(Base, {
|
|
116
|
-
0: NetworkOrCORSError,
|
|
117
|
-
NetworkOrCORSError,
|
|
118
|
-
400: BadRequest,
|
|
119
|
-
BadRequest,
|
|
120
|
-
401: Unauthorized,
|
|
121
|
-
Unauthorized,
|
|
122
|
-
402: PaymentRequired,
|
|
123
|
-
PaymentRequired,
|
|
124
|
-
403: Forbidden,
|
|
125
|
-
Forbidden,
|
|
126
|
-
404: NotFound,
|
|
127
|
-
NotFound,
|
|
128
|
-
405: MethodNotAllowed,
|
|
129
|
-
MethodNotAllowed,
|
|
130
|
-
406: NotAcceptable,
|
|
131
|
-
NotAcceptable,
|
|
132
|
-
407: ProxyAuthenticationRequired,
|
|
133
|
-
ProxyAuthenticationRequired,
|
|
134
|
-
408: RequestTimeout,
|
|
135
|
-
RequestTimeout,
|
|
136
|
-
409: Conflict,
|
|
137
|
-
Conflict,
|
|
138
|
-
410: Gone,
|
|
139
|
-
Gone,
|
|
140
|
-
411: LengthRequired,
|
|
141
|
-
LengthRequired,
|
|
142
|
-
412: PreconditionFailed,
|
|
143
|
-
PreconditionFailed,
|
|
144
|
-
413: RequestEntityTooLarge,
|
|
145
|
-
RequestEntityTooLarge,
|
|
146
|
-
414: RequestUriTooLong,
|
|
147
|
-
RequestUriTooLong,
|
|
148
|
-
415: UnsupportedMediaType,
|
|
149
|
-
UnsupportedMediaType,
|
|
150
|
-
416: RequestRangeNotSatisfiable,
|
|
151
|
-
RequestRangeNotSatisfiable,
|
|
152
|
-
417: ExpectationFailed,
|
|
153
|
-
ExpectationFailed,
|
|
154
|
-
429: TooManyRequests,
|
|
155
|
-
TooManyRequests,
|
|
156
|
-
500: InternalServerError,
|
|
157
|
-
InternalServerError,
|
|
158
|
-
501: NotImplemented,
|
|
159
|
-
NotImplemented,
|
|
160
|
-
502: BadGateway,
|
|
161
|
-
BadGateway,
|
|
162
|
-
503: ServiceUnavailable,
|
|
163
|
-
ServiceUnavailable,
|
|
164
|
-
504: GatewayTimeout,
|
|
165
|
-
GatewayTimeout,
|
|
166
|
-
505: HttpVersionNotSupported,
|
|
167
|
-
HttpVersionNotSupported,
|
|
168
|
-
select(statusCode) {
|
|
169
|
-
if (typeof statusCode === 'undefined' || statusCode === null) {
|
|
170
|
-
return Base;
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
statusCode = statusCode.statusCode || statusCode;
|
|
174
|
-
const E = Base[statusCode];
|
|
175
|
-
|
|
176
|
-
if (E) {
|
|
177
|
-
return E;
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
// Fallback to the default for the category (e.g. BadRequest for 429)
|
|
181
|
-
statusCode = `${statusCode.toString().split('').shift()}00`;
|
|
182
|
-
statusCode = parseInt(statusCode, 10);
|
|
183
|
-
|
|
184
|
-
return Base[statusCode] || Base;
|
|
185
|
-
},
|
|
186
|
-
});
|
|
187
|
-
}
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @param {Error} Base
|
|
7
|
+
* @returns {undefined}
|
|
8
|
+
*/
|
|
9
|
+
export default function makeSubTypes(Base) {
|
|
10
|
+
/**
|
|
11
|
+
* NetworkOrCORSError
|
|
12
|
+
*/
|
|
13
|
+
class NetworkOrCORSError extends Base {}
|
|
14
|
+
/**
|
|
15
|
+
* BadRequest
|
|
16
|
+
*/
|
|
17
|
+
class BadRequest extends Base {}
|
|
18
|
+
/**
|
|
19
|
+
* Unauthorized
|
|
20
|
+
*/
|
|
21
|
+
class Unauthorized extends BadRequest {}
|
|
22
|
+
/**
|
|
23
|
+
* PaymentRequired
|
|
24
|
+
*/
|
|
25
|
+
class PaymentRequired extends BadRequest {}
|
|
26
|
+
/**
|
|
27
|
+
* Forbidden
|
|
28
|
+
*/
|
|
29
|
+
class Forbidden extends BadRequest {}
|
|
30
|
+
/**
|
|
31
|
+
* NotFound
|
|
32
|
+
*/
|
|
33
|
+
class NotFound extends BadRequest {}
|
|
34
|
+
/**
|
|
35
|
+
* MethodNotAllowed
|
|
36
|
+
*/
|
|
37
|
+
class MethodNotAllowed extends BadRequest {}
|
|
38
|
+
/**
|
|
39
|
+
* NotAcceptable
|
|
40
|
+
*/
|
|
41
|
+
class NotAcceptable extends BadRequest {}
|
|
42
|
+
/**
|
|
43
|
+
* ProxyAuthenticationRequired
|
|
44
|
+
*/
|
|
45
|
+
class ProxyAuthenticationRequired extends BadRequest {}
|
|
46
|
+
/**
|
|
47
|
+
* RequestTimeout
|
|
48
|
+
*/
|
|
49
|
+
class RequestTimeout extends BadRequest {}
|
|
50
|
+
/**
|
|
51
|
+
* Conflict
|
|
52
|
+
*/
|
|
53
|
+
class Conflict extends BadRequest {}
|
|
54
|
+
/**
|
|
55
|
+
* Gone
|
|
56
|
+
*/
|
|
57
|
+
class Gone extends BadRequest {}
|
|
58
|
+
/**
|
|
59
|
+
* LengthRequired
|
|
60
|
+
*/
|
|
61
|
+
class LengthRequired extends BadRequest {}
|
|
62
|
+
/**
|
|
63
|
+
* PreconditionFailed
|
|
64
|
+
*/
|
|
65
|
+
class PreconditionFailed extends BadRequest {}
|
|
66
|
+
/**
|
|
67
|
+
* RequestEntityTooLarge
|
|
68
|
+
*/
|
|
69
|
+
class RequestEntityTooLarge extends BadRequest {}
|
|
70
|
+
/**
|
|
71
|
+
* RequestUriTooLong
|
|
72
|
+
*/
|
|
73
|
+
class RequestUriTooLong extends BadRequest {}
|
|
74
|
+
/**
|
|
75
|
+
* UnsupportedMediaType
|
|
76
|
+
*/
|
|
77
|
+
class UnsupportedMediaType extends BadRequest {}
|
|
78
|
+
/**
|
|
79
|
+
* RequestRangeNotSatisfiable
|
|
80
|
+
*/
|
|
81
|
+
class RequestRangeNotSatisfiable extends BadRequest {}
|
|
82
|
+
/**
|
|
83
|
+
* ExpectationFailed
|
|
84
|
+
*/
|
|
85
|
+
class ExpectationFailed extends BadRequest {}
|
|
86
|
+
/**
|
|
87
|
+
* TooManyRequests
|
|
88
|
+
*/
|
|
89
|
+
class TooManyRequests extends BadRequest {}
|
|
90
|
+
/**
|
|
91
|
+
* InternalServerError
|
|
92
|
+
*/
|
|
93
|
+
class InternalServerError extends Base {}
|
|
94
|
+
/**
|
|
95
|
+
* NotImplemented
|
|
96
|
+
*/
|
|
97
|
+
class NotImplemented extends InternalServerError {}
|
|
98
|
+
/**
|
|
99
|
+
* BadGateway
|
|
100
|
+
*/
|
|
101
|
+
class BadGateway extends InternalServerError {}
|
|
102
|
+
/**
|
|
103
|
+
* ServiceUnavailable
|
|
104
|
+
*/
|
|
105
|
+
class ServiceUnavailable extends InternalServerError {}
|
|
106
|
+
/**
|
|
107
|
+
* GatewayTimeout
|
|
108
|
+
*/
|
|
109
|
+
class GatewayTimeout extends InternalServerError {}
|
|
110
|
+
/**
|
|
111
|
+
* HttpVersionNotSupported
|
|
112
|
+
*/
|
|
113
|
+
class HttpVersionNotSupported extends InternalServerError {}
|
|
114
|
+
|
|
115
|
+
Object.assign(Base, {
|
|
116
|
+
0: NetworkOrCORSError,
|
|
117
|
+
NetworkOrCORSError,
|
|
118
|
+
400: BadRequest,
|
|
119
|
+
BadRequest,
|
|
120
|
+
401: Unauthorized,
|
|
121
|
+
Unauthorized,
|
|
122
|
+
402: PaymentRequired,
|
|
123
|
+
PaymentRequired,
|
|
124
|
+
403: Forbidden,
|
|
125
|
+
Forbidden,
|
|
126
|
+
404: NotFound,
|
|
127
|
+
NotFound,
|
|
128
|
+
405: MethodNotAllowed,
|
|
129
|
+
MethodNotAllowed,
|
|
130
|
+
406: NotAcceptable,
|
|
131
|
+
NotAcceptable,
|
|
132
|
+
407: ProxyAuthenticationRequired,
|
|
133
|
+
ProxyAuthenticationRequired,
|
|
134
|
+
408: RequestTimeout,
|
|
135
|
+
RequestTimeout,
|
|
136
|
+
409: Conflict,
|
|
137
|
+
Conflict,
|
|
138
|
+
410: Gone,
|
|
139
|
+
Gone,
|
|
140
|
+
411: LengthRequired,
|
|
141
|
+
LengthRequired,
|
|
142
|
+
412: PreconditionFailed,
|
|
143
|
+
PreconditionFailed,
|
|
144
|
+
413: RequestEntityTooLarge,
|
|
145
|
+
RequestEntityTooLarge,
|
|
146
|
+
414: RequestUriTooLong,
|
|
147
|
+
RequestUriTooLong,
|
|
148
|
+
415: UnsupportedMediaType,
|
|
149
|
+
UnsupportedMediaType,
|
|
150
|
+
416: RequestRangeNotSatisfiable,
|
|
151
|
+
RequestRangeNotSatisfiable,
|
|
152
|
+
417: ExpectationFailed,
|
|
153
|
+
ExpectationFailed,
|
|
154
|
+
429: TooManyRequests,
|
|
155
|
+
TooManyRequests,
|
|
156
|
+
500: InternalServerError,
|
|
157
|
+
InternalServerError,
|
|
158
|
+
501: NotImplemented,
|
|
159
|
+
NotImplemented,
|
|
160
|
+
502: BadGateway,
|
|
161
|
+
BadGateway,
|
|
162
|
+
503: ServiceUnavailable,
|
|
163
|
+
ServiceUnavailable,
|
|
164
|
+
504: GatewayTimeout,
|
|
165
|
+
GatewayTimeout,
|
|
166
|
+
505: HttpVersionNotSupported,
|
|
167
|
+
HttpVersionNotSupported,
|
|
168
|
+
select(statusCode) {
|
|
169
|
+
if (typeof statusCode === 'undefined' || statusCode === null) {
|
|
170
|
+
return Base;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
statusCode = statusCode.statusCode || statusCode;
|
|
174
|
+
const E = Base[statusCode];
|
|
175
|
+
|
|
176
|
+
if (E) {
|
|
177
|
+
return E;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// Fallback to the default for the category (e.g. BadRequest for 429)
|
|
181
|
+
statusCode = `${statusCode.toString().split('').shift()}00`;
|
|
182
|
+
statusCode = parseInt(statusCode, 10);
|
|
183
|
+
|
|
184
|
+
return Base[statusCode] || Base;
|
|
185
|
+
},
|
|
186
|
+
});
|
|
187
|
+
}
|
package/src/http-error.js
CHANGED
|
@@ -1,147 +1,147 @@
|
|
|
1
|
-
/*!
|
|
2
|
-
* Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import {pick} from 'lodash';
|
|
6
|
-
import {Exception} from '@webex/common';
|
|
7
|
-
|
|
8
|
-
import makeSubTypes from './http-error-subtypes';
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Base HttpError class. Unlikely to be thrown directly, but handy for general
|
|
12
|
-
* type comparison.
|
|
13
|
-
*/
|
|
14
|
-
export default class HttpError extends Exception {
|
|
15
|
-
/**
|
|
16
|
-
* @example Extend via
|
|
17
|
-
* MyError extends HttpError {
|
|
18
|
-
* static errorKeys = HttpError.errorKeys.concat([
|
|
19
|
-
* `key1`,
|
|
20
|
-
* `key2`
|
|
21
|
-
* ])
|
|
22
|
-
* }
|
|
23
|
-
*
|
|
24
|
-
* @type {Array}
|
|
25
|
-
*/
|
|
26
|
-
static errorKeys = ['error', 'errorString', 'response', 'errorResponse', 'message', 'msg'];
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* Default error string if no error can be extracted from the http response
|
|
30
|
-
* @type {string}
|
|
31
|
-
*/
|
|
32
|
-
static defaultMessage = 'An error was received while trying to fulfill the request';
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* Parses HttpResponse objects for useful information (status, headers, etc)
|
|
36
|
-
* as well as attempting to extract a useful error message.
|
|
37
|
-
* @param {HttpResponse} res
|
|
38
|
-
* @returns {string}
|
|
39
|
-
*/
|
|
40
|
-
parse(res) {
|
|
41
|
-
// complexity is high here because of all the default values below.
|
|
42
|
-
/* eslint complexity: [0] */
|
|
43
|
-
let {body} = res;
|
|
44
|
-
let message;
|
|
45
|
-
|
|
46
|
-
switch (typeof body) {
|
|
47
|
-
case 'string':
|
|
48
|
-
try {
|
|
49
|
-
body = JSON.parse(body);
|
|
50
|
-
message = this.parseObject(body);
|
|
51
|
-
} catch (err) {
|
|
52
|
-
message = body;
|
|
53
|
-
}
|
|
54
|
-
break;
|
|
55
|
-
case 'object':
|
|
56
|
-
message = this.parseObject(body);
|
|
57
|
-
break;
|
|
58
|
-
default:
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
if (!message) {
|
|
62
|
-
message = this.defaultMessage;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
Object.defineProperties(this, {
|
|
66
|
-
body: {
|
|
67
|
-
enumerable: false,
|
|
68
|
-
value: body,
|
|
69
|
-
},
|
|
70
|
-
httpVersion: {
|
|
71
|
-
enumerable: false,
|
|
72
|
-
value: res.httpVersion,
|
|
73
|
-
},
|
|
74
|
-
headers: {
|
|
75
|
-
enumerable: false,
|
|
76
|
-
value: res.headers || {},
|
|
77
|
-
},
|
|
78
|
-
rawHeaders: {
|
|
79
|
-
enumerable: false,
|
|
80
|
-
value: res.rawHeaders || [],
|
|
81
|
-
},
|
|
82
|
-
trailers: {
|
|
83
|
-
enumerable: false,
|
|
84
|
-
value: res.trailers || {},
|
|
85
|
-
},
|
|
86
|
-
rawTrailers: {
|
|
87
|
-
enumerable: false,
|
|
88
|
-
value: res.rawTrailers || [],
|
|
89
|
-
},
|
|
90
|
-
method: {
|
|
91
|
-
enumerable: false,
|
|
92
|
-
value: res.method,
|
|
93
|
-
},
|
|
94
|
-
url: {
|
|
95
|
-
enumerable: false,
|
|
96
|
-
value: res.url,
|
|
97
|
-
},
|
|
98
|
-
statusCode: {
|
|
99
|
-
enumerable: false,
|
|
100
|
-
value: res.statusCode,
|
|
101
|
-
},
|
|
102
|
-
statusMessage: {
|
|
103
|
-
enumerable: false,
|
|
104
|
-
value: res.statusMessage,
|
|
105
|
-
},
|
|
106
|
-
socket: {
|
|
107
|
-
enumerable: false,
|
|
108
|
-
value: res.socket,
|
|
109
|
-
},
|
|
110
|
-
_res: {
|
|
111
|
-
enumerable: false,
|
|
112
|
-
value: res,
|
|
113
|
-
},
|
|
114
|
-
});
|
|
115
|
-
|
|
116
|
-
return message;
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
/**
|
|
120
|
-
* Recursively parses an error body looking for a likely error candidate
|
|
121
|
-
* @param {object} body
|
|
122
|
-
* @returns {string}
|
|
123
|
-
*/
|
|
124
|
-
parseObject(body) {
|
|
125
|
-
// Search body for common names of error strings
|
|
126
|
-
const messages = Object.values(pick(body, HttpError.errorKeys));
|
|
127
|
-
|
|
128
|
-
// If no error candidate was found, stringify the entire body
|
|
129
|
-
if (messages.length === 0) {
|
|
130
|
-
return JSON.stringify(body, null, 2);
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
// Assume the first key found was the error explanation
|
|
134
|
-
const message = messages[0];
|
|
135
|
-
|
|
136
|
-
// If the explanation is an object, recurse and try again
|
|
137
|
-
if (typeof message === 'object') {
|
|
138
|
-
return this.parseObject(message);
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
// Return the first key
|
|
142
|
-
return message;
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
makeSubTypes(HttpError);
|
|
147
|
-
HttpError.makeSubTypes = makeSubTypes;
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import {pick} from 'lodash';
|
|
6
|
+
import {Exception} from '@webex/common';
|
|
7
|
+
|
|
8
|
+
import makeSubTypes from './http-error-subtypes';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Base HttpError class. Unlikely to be thrown directly, but handy for general
|
|
12
|
+
* type comparison.
|
|
13
|
+
*/
|
|
14
|
+
export default class HttpError extends Exception {
|
|
15
|
+
/**
|
|
16
|
+
* @example Extend via
|
|
17
|
+
* MyError extends HttpError {
|
|
18
|
+
* static errorKeys = HttpError.errorKeys.concat([
|
|
19
|
+
* `key1`,
|
|
20
|
+
* `key2`
|
|
21
|
+
* ])
|
|
22
|
+
* }
|
|
23
|
+
*
|
|
24
|
+
* @type {Array}
|
|
25
|
+
*/
|
|
26
|
+
static errorKeys = ['error', 'errorString', 'response', 'errorResponse', 'message', 'msg'];
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Default error string if no error can be extracted from the http response
|
|
30
|
+
* @type {string}
|
|
31
|
+
*/
|
|
32
|
+
static defaultMessage = 'An error was received while trying to fulfill the request';
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Parses HttpResponse objects for useful information (status, headers, etc)
|
|
36
|
+
* as well as attempting to extract a useful error message.
|
|
37
|
+
* @param {HttpResponse} res
|
|
38
|
+
* @returns {string}
|
|
39
|
+
*/
|
|
40
|
+
parse(res) {
|
|
41
|
+
// complexity is high here because of all the default values below.
|
|
42
|
+
/* eslint complexity: [0] */
|
|
43
|
+
let {body} = res;
|
|
44
|
+
let message;
|
|
45
|
+
|
|
46
|
+
switch (typeof body) {
|
|
47
|
+
case 'string':
|
|
48
|
+
try {
|
|
49
|
+
body = JSON.parse(body);
|
|
50
|
+
message = this.parseObject(body);
|
|
51
|
+
} catch (err) {
|
|
52
|
+
message = body;
|
|
53
|
+
}
|
|
54
|
+
break;
|
|
55
|
+
case 'object':
|
|
56
|
+
message = this.parseObject(body);
|
|
57
|
+
break;
|
|
58
|
+
default:
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
if (!message) {
|
|
62
|
+
message = this.defaultMessage;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
Object.defineProperties(this, {
|
|
66
|
+
body: {
|
|
67
|
+
enumerable: false,
|
|
68
|
+
value: body,
|
|
69
|
+
},
|
|
70
|
+
httpVersion: {
|
|
71
|
+
enumerable: false,
|
|
72
|
+
value: res.httpVersion,
|
|
73
|
+
},
|
|
74
|
+
headers: {
|
|
75
|
+
enumerable: false,
|
|
76
|
+
value: res.headers || {},
|
|
77
|
+
},
|
|
78
|
+
rawHeaders: {
|
|
79
|
+
enumerable: false,
|
|
80
|
+
value: res.rawHeaders || [],
|
|
81
|
+
},
|
|
82
|
+
trailers: {
|
|
83
|
+
enumerable: false,
|
|
84
|
+
value: res.trailers || {},
|
|
85
|
+
},
|
|
86
|
+
rawTrailers: {
|
|
87
|
+
enumerable: false,
|
|
88
|
+
value: res.rawTrailers || [],
|
|
89
|
+
},
|
|
90
|
+
method: {
|
|
91
|
+
enumerable: false,
|
|
92
|
+
value: res.method,
|
|
93
|
+
},
|
|
94
|
+
url: {
|
|
95
|
+
enumerable: false,
|
|
96
|
+
value: res.url,
|
|
97
|
+
},
|
|
98
|
+
statusCode: {
|
|
99
|
+
enumerable: false,
|
|
100
|
+
value: res.statusCode,
|
|
101
|
+
},
|
|
102
|
+
statusMessage: {
|
|
103
|
+
enumerable: false,
|
|
104
|
+
value: res.statusMessage,
|
|
105
|
+
},
|
|
106
|
+
socket: {
|
|
107
|
+
enumerable: false,
|
|
108
|
+
value: res.socket,
|
|
109
|
+
},
|
|
110
|
+
_res: {
|
|
111
|
+
enumerable: false,
|
|
112
|
+
value: res,
|
|
113
|
+
},
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
return message;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Recursively parses an error body looking for a likely error candidate
|
|
121
|
+
* @param {object} body
|
|
122
|
+
* @returns {string}
|
|
123
|
+
*/
|
|
124
|
+
parseObject(body) {
|
|
125
|
+
// Search body for common names of error strings
|
|
126
|
+
const messages = Object.values(pick(body, HttpError.errorKeys));
|
|
127
|
+
|
|
128
|
+
// If no error candidate was found, stringify the entire body
|
|
129
|
+
if (messages.length === 0) {
|
|
130
|
+
return JSON.stringify(body, null, 2);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// Assume the first key found was the error explanation
|
|
134
|
+
const message = messages[0];
|
|
135
|
+
|
|
136
|
+
// If the explanation is an object, recurse and try again
|
|
137
|
+
if (typeof message === 'object') {
|
|
138
|
+
return this.parseObject(message);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// Return the first key
|
|
142
|
+
return message;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
makeSubTypes(HttpError);
|
|
147
|
+
HttpError.makeSubTypes = makeSubTypes;
|