@compassdigital/sdk.typescript 3.0.0-beta.18 → 3.0.0-beta.19
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/lib/base.d.ts +5 -4
- package/lib/base.d.ts.map +1 -1
- package/lib/base.js +53 -13
- package/lib/base.js.map +1 -1
- package/package.json +1 -1
- package/src/base.ts +57 -21
- package/test/client.test.ts +33 -5
package/lib/base.d.ts
CHANGED
|
@@ -27,6 +27,7 @@ export interface ResponseData {
|
|
|
27
27
|
ok: boolean;
|
|
28
28
|
status: number;
|
|
29
29
|
body: string;
|
|
30
|
+
err?: any;
|
|
30
31
|
}
|
|
31
32
|
/**
|
|
32
33
|
* A function that performs an https request.
|
|
@@ -74,7 +75,7 @@ export declare class ResponsePromise<T> implements Promise<T> {
|
|
|
74
75
|
/**
|
|
75
76
|
* Either a response body or a service error.
|
|
76
77
|
*/
|
|
77
|
-
declare type EitherResponse<T> = {
|
|
78
|
+
export declare type EitherResponse<T> = {
|
|
78
79
|
ok: true;
|
|
79
80
|
data: T;
|
|
80
81
|
err: null;
|
|
@@ -134,9 +135,10 @@ export declare abstract class BaseServiceClient {
|
|
|
134
135
|
*/
|
|
135
136
|
private fetch;
|
|
136
137
|
/**
|
|
137
|
-
* Returns true if the
|
|
138
|
+
* Returns true if the status code represents a transient error
|
|
139
|
+
* or it's a network error.
|
|
138
140
|
*/
|
|
139
|
-
private
|
|
141
|
+
private should_retry;
|
|
140
142
|
/**
|
|
141
143
|
* Returns the merged options.
|
|
142
144
|
*/
|
|
@@ -153,5 +155,4 @@ export declare abstract class BaseServiceClient {
|
|
|
153
155
|
*/
|
|
154
156
|
private _request;
|
|
155
157
|
}
|
|
156
|
-
export {};
|
|
157
158
|
//# sourceMappingURL=base.d.ts.map
|
package/lib/base.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../src/base.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,cAAc;IAE7B,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAEjC,KAAK,CAAC,EAAE,OAAO,CAAC;IAEhB,KAAK,CAAC,EAAE,MAAM,CAAC;IAGf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB,SAAS,CAAC,EAAE,WAAW,CAAC;CACzB;AAED;;;GAGG;AACH,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../src/base.ts"],"names":[],"mappings":"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"}
|
package/lib/base.js
CHANGED
|
@@ -234,14 +234,26 @@ var ServiceError = /** @class */ (function (_super) {
|
|
|
234
234
|
ServiceError.from_res = function (res) {
|
|
235
235
|
var message = res.body;
|
|
236
236
|
var code = res.status;
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
if (
|
|
240
|
-
|
|
241
|
-
message = data.message || data.error;
|
|
237
|
+
if (res.err) {
|
|
238
|
+
// network error
|
|
239
|
+
if (res.err instanceof Error) {
|
|
240
|
+
message = res.err.message;
|
|
242
241
|
}
|
|
242
|
+
else {
|
|
243
|
+
message = "Network Error";
|
|
244
|
+
}
|
|
245
|
+
code = 0;
|
|
246
|
+
}
|
|
247
|
+
else {
|
|
248
|
+
try {
|
|
249
|
+
var data = JSON.parse(res.body);
|
|
250
|
+
if (data.code && (data.message || data.error)) {
|
|
251
|
+
code = data.code;
|
|
252
|
+
message = data.message || data.error;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
catch (_) { }
|
|
243
256
|
}
|
|
244
|
-
catch (_) { }
|
|
245
257
|
var err = new ServiceError(res.status, code, message);
|
|
246
258
|
// override the stack trace so that it doesn't include the from_res helper.
|
|
247
259
|
if (Error.captureStackTrace) {
|
|
@@ -290,7 +302,7 @@ var BaseServiceClient = /** @class */ (function () {
|
|
|
290
302
|
*/
|
|
291
303
|
BaseServiceClient.prototype.fetch = function (req, options) {
|
|
292
304
|
return __awaiter(this, void 0, void 0, function () {
|
|
293
|
-
var res;
|
|
305
|
+
var res, err_3;
|
|
294
306
|
var _b;
|
|
295
307
|
return __generator(this, function (_c) {
|
|
296
308
|
switch (_c.label) {
|
|
@@ -298,29 +310,57 @@ var BaseServiceClient = /** @class */ (function () {
|
|
|
298
310
|
if (options === null || options === void 0 ? void 0 : options.intercept) {
|
|
299
311
|
return [2 /*return*/, options.intercept(req, this.fetch.bind(this))];
|
|
300
312
|
}
|
|
313
|
+
_c.label = 1;
|
|
314
|
+
case 1:
|
|
315
|
+
_c.trys.push([1, 4, , 5]);
|
|
301
316
|
return [4 /*yield*/, (0, cross_fetch_1.default)(req.url, {
|
|
302
317
|
method: req.method,
|
|
303
318
|
body: req.body,
|
|
304
319
|
headers: req.headers,
|
|
305
320
|
})];
|
|
306
|
-
case
|
|
321
|
+
case 2:
|
|
307
322
|
res = _c.sent();
|
|
308
323
|
_b = {
|
|
309
324
|
ok: res.ok,
|
|
310
325
|
status: res.status
|
|
311
326
|
};
|
|
312
327
|
return [4 /*yield*/, res.text()];
|
|
313
|
-
case
|
|
328
|
+
case 3: return [2 /*return*/, (_b.body = _c.sent(),
|
|
314
329
|
_b)];
|
|
330
|
+
case 4:
|
|
331
|
+
err_3 = _c.sent();
|
|
332
|
+
return [2 /*return*/, {
|
|
333
|
+
ok: false,
|
|
334
|
+
status: 0,
|
|
335
|
+
body: "",
|
|
336
|
+
err: err_3,
|
|
337
|
+
}];
|
|
338
|
+
case 5: return [2 /*return*/];
|
|
315
339
|
}
|
|
316
340
|
});
|
|
317
341
|
});
|
|
318
342
|
};
|
|
319
343
|
/**
|
|
320
|
-
* Returns true if the
|
|
344
|
+
* Returns true if the status code represents a transient error
|
|
345
|
+
* or it's a network error.
|
|
321
346
|
*/
|
|
322
|
-
BaseServiceClient.prototype.
|
|
323
|
-
|
|
347
|
+
BaseServiceClient.prototype.should_retry = function (res) {
|
|
348
|
+
if (res.err) {
|
|
349
|
+
return true;
|
|
350
|
+
}
|
|
351
|
+
switch (res.status) {
|
|
352
|
+
case 408: // timeout
|
|
353
|
+
case 413: // too large
|
|
354
|
+
case 429: // too many requests
|
|
355
|
+
case 500: // generic error response
|
|
356
|
+
case 502: // invalid upstream response
|
|
357
|
+
case 503: // service unavailable
|
|
358
|
+
case 504: // gateway timeout
|
|
359
|
+
case 522: // tcp connection timeout
|
|
360
|
+
return true;
|
|
361
|
+
default:
|
|
362
|
+
return false;
|
|
363
|
+
}
|
|
324
364
|
};
|
|
325
365
|
/**
|
|
326
366
|
* Returns the merged options.
|
|
@@ -371,7 +411,7 @@ var BaseServiceClient = /** @class */ (function () {
|
|
|
371
411
|
if (options.debug) {
|
|
372
412
|
console.log("ERR(" + res.status + ")", url, err.message);
|
|
373
413
|
}
|
|
374
|
-
if (typeof options.retry === "number" && options.retry > 0 &&
|
|
414
|
+
if (typeof options.retry === "number" && options.retry > 0 && this.should_retry(res)) {
|
|
375
415
|
options.retry--;
|
|
376
416
|
return [2 /*return*/, this.request(service, name, method, route, body, options)];
|
|
377
417
|
}
|
package/lib/base.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base.js","sourceRoot":"","sources":["../src/base.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACA,4DAAgC;
|
|
1
|
+
{"version":3,"file":"base.js","sourceRoot":"","sources":["../src/base.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACA,4DAAgC;AAsDhC;;;GAGG;AACH;IAOE,yBAAoB,OAAmB;QAAnB,YAAO,GAAP,OAAO,CAAY;QALvC;;WAEG;QACH,QAAoB,GAAG,0BAA0B,CAAC;IAER,CAAC;IAE3C;;OAEG;IACH,8BAAI,GAAJ,UACE,WAAqE,EACrE,UAAuE;QAEvE,OAAO,IAAI,eAAe,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC,CAAC;IACzE,CAAC;IAED;;OAEG;IACH,+BAAK,GAAL,UACE,UAAqE;QAErE,OAAO,IAAI,eAAe,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC;IAC7D,CAAC;IAED;;OAEG;IACH,iCAAO,GAAP,UAAQ,SAA+B;QACrC,OAAO,IAAI,eAAe,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC;IAC9D,CAAC;IAED;;;;OAIG;IACH,gCAAM,GAAN;QAAO,eAAkB;aAAlB,UAAkB,EAAlB,qBAAkB,EAAlB,IAAkB;YAAlB,0BAAkB;;QACvB,OAAO,IAAI,eAAe,CAAC,YAAY,CAAC,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;IACvE,CAAC;IAED;;;OAGG;IACH,iCAAO,GAAP;QAAQ,eAAkB;aAAlB,UAAkB,EAAlB,qBAAkB,EAAlB,IAAkB;YAAlB,0BAAkB;;QACxB,OAAO,IAAI,eAAe,CAAC,YAAY,CAAC,OAAO,CAAI,KAAK,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;IAC3E,CAAC;IACH,sBAAC;AAAD,CAAC,AAnDD,IAmDC;AAnDY,0CAAe;KAKzB,MAAM,CAAC,WAAW;AA4DrB;;GAEG;AACH;IAAkC,gCAAK;IACrC,sBACS,MAAc,EAAE,cAAc;IAC9B,IAAY,EAAI,qBAAqB;IAC5C,OAAe,CAAQ,wBAAwB;;QAHjD,YAKE,kBAAM,OAAO,CAAC,SAKf;QATQ,YAAM,GAAN,MAAM,CAAQ;QACd,UAAI,GAAJ,IAAI,CAAQ;QAInB,KAAI,CAAC,IAAI,GAAG,kBAAgB,IAAI,MAAG,CAAC;QAEpC,0DAA0D;QAC1D,MAAM,CAAC,cAAc,CAAC,KAAI,EAAE,YAAY,CAAC,SAAS,CAAC,CAAC;;IACtD,CAAC;IAED;;;OAGG;IACI,mBAAM,GAAb,UAAc,GAAQ;QACpB,IAAI,GAAG,YAAY,YAAY,EAAE;YAC/B,OAAO,GAAG,CAAC,MAAM,CAAC;SACnB;QACD,OAAO,CAAC,CAAC,CAAC;IACZ,CAAC;IAED;;;OAGG;IACI,iBAAI,GAAX,UAAY,GAAQ;QAClB,IAAI,GAAG,YAAY,YAAY,EAAE;YAC/B,OAAO,GAAG,CAAC,IAAI,CAAC;SACjB;QACD,OAAO,CAAC,CAAC,CAAC;IACZ,CAAC;IAED;;;;OAIG;IACU,mBAAM,GAAnB,UAAuB,KAAe,EAAE,QAAoB;;;;;;;wBAEjD,qBAAM,QAAQ,EAAA;4BAArB,sBAAO,SAAc,EAAC;;;wBAEtB,IAAI,KAAG,YAAY,YAAY,EAAE;4BAC/B,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE;gCACtB,sBAAO,IAAI,EAAC;6BACb;4BACD,WAAwB,EAAL,eAAK,EAAL,mBAAK,EAAL,IAAK,EAAE;gCAAf,IAAI;gCACb,IAAI,KAAG,CAAC,MAAM,KAAK,IAAI,IAAI,KAAG,CAAC,IAAI,KAAK,IAAI,EAAE;oCAC5C,sBAAO,IAAI,EAAC;iCACb;6BACF;yBACF;wBACD,MAAM,KAAG,CAAC;;;;;KAEb;IAED;;OAEG;IACU,oBAAO,GAApB,UAAwB,KAAe,EAAE,QAAoB;;;;;;;wBAE5C,qBAAM,QAAQ,EAAA;;wBAArB,IAAI,GAAG,SAAc;wBAC3B,sBAAO,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,MAAA,EAAE,GAAG,EAAE,IAAI,EAAE,EAAC;;;wBAErC,IAAI,KAAG,YAAY,YAAY,EAAE;4BAC/B,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE;gCACtB,sBAAO,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,OAAA,EAAE,EAAA;6BACtC;4BACD,WAAwB,EAAL,eAAK,EAAL,mBAAK,EAAL,IAAK,EAAE;gCAAf,IAAI;gCACb,IAAI,KAAG,CAAC,MAAM,KAAK,IAAI,IAAI,KAAG,CAAC,IAAI,KAAK,IAAI,EAAE;oCAC5C,sBAAO,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,OAAA,EAAE,EAAC;iCACvC;6BACF;yBACF;wBACD,MAAM,KAAG,CAAC;;;;;KAEb;IAED;;OAEG;IACI,qBAAQ,GAAf,UAAgB,GAAiB;QAC/B,IAAI,OAAO,GAAG,GAAG,CAAC,IAAI,CAAC;QACvB,IAAI,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC;QACtB,IAAI,GAAG,CAAC,GAAG,EAAE;YACX,gBAAgB;YAChB,IAAI,GAAG,CAAC,GAAG,YAAY,KAAK,EAAE;gBAC5B,OAAO,GAAG,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC;aAC3B;iBAAM;gBACL,OAAO,GAAG,eAAe,CAAC;aAC3B;YACD,IAAI,GAAG,CAAC,CAAC;SACV;aAAM;YACL,IAAI;gBACF,IAAI,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;gBAChC,IAAI,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,KAAK,CAAC,EAAE;oBAC7C,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;oBACjB,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,KAAK,CAAC;iBACtC;aACF;YAAC,OAAO,CAAC,EAAE,GAAE;SACf;QACD,IAAM,GAAG,GAAG,IAAI,YAAY,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;QACxD,2EAA2E;QAC3E,IAAI,KAAK,CAAC,iBAAiB,EAAE;YAC3B,KAAK,CAAC,iBAAiB,CAAC,GAAG,EAAE,YAAY,CAAC,QAAQ,CAAC,CAAC;SACrD;QACD,OAAO,GAAG,CAAC;IACb,CAAC;IACH,mBAAC;AAAD,CAAC,AA9GD,CAAkC,KAAK,GA8GtC;AA9GY,oCAAY;AAgHzB;;;GAGG;AACH;IAGE,2BAAY,OAAwB;QAClC,IAAI,CAAC,OAAO,GAAG,OAAO,aAAP,OAAO,cAAP,OAAO,GAAI,EAAE,CAAC;IAC/B,CAAC;IAED;;OAEG;IACK,qCAAS,GAAjB,UAAkB,KAAa,EAAE,EAA2C,EAAE,MAAW;YAAtD,QAAQ,cAAA,EAAE,aAAa,EAAb,KAAK,mBAAG,KAAK,KAAA;QACxD,IAAI,GAAG,GAAG,oCAAkC,KAAK,GAAG,KAAO,CAAC;QAC5D,wCAAwC;QACxC,IAAI,QAAQ,EAAE;YACZ,IAAI,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE;gBAC1B,QAAQ,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;aAClC;YACD,GAAG,GAAG,KAAG,QAAQ,GAAG,KAAO,CAAC;SAC7B;QACD,wBAAwB;QACxB,IAAM,KAAK,GAAa,EAAE,CAAC;QAC3B,KAA4B,UAAsB,EAAtB,KAAA,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAtB,cAAsB,EAAtB,IAAsB,EAAE;YAAzC,IAAA,WAAa,EAAZ,MAAI,QAAA,EAAE,KAAK,QAAA;YACrB,KAAK,CAAC,IAAI,CAAI,kBAAkB,CAAC,MAAI,CAAC,SAAI,kBAAkB,CAAC,KAAY,CAAG,CAAC,CAAC;SAC/E;QACD,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE;YACpB,GAAG,IAAI,GAAG,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;SAC9B;QACD,OAAO,GAAG,CAAC;IACb,CAAC;IAED;;;OAGG;IACW,iCAAK,GAAnB,UAAoB,GAAgB,EAAE,OAAwB;;;;;;;wBAC5D,IAAI,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,SAAS,EAAE;4BACtB,sBAAO,OAAO,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,EAAC;yBACtD;;;;wBAEa,qBAAM,IAAA,qBAAK,EAAC,GAAG,CAAC,GAAG,EAAE;gCAC/B,MAAM,EAAE,GAAG,CAAC,MAAM;gCAClB,IAAI,EAAE,GAAG,CAAC,IAAI;gCACd,OAAO,EAAE,GAAG,CAAC,OAAO;6BACrB,CAAC,EAAA;;wBAJI,GAAG,GAAG,SAIV;;4BAEA,EAAE,EAAE,GAAG,CAAC,EAAE;4BACV,MAAM,EAAE,GAAG,CAAC,MAAM;;wBACZ,qBAAM,GAAG,CAAC,IAAI,EAAE,EAAA;4BAHxB,uBAGE,OAAI,GAAE,SAAgB;iCACtB;;;wBAEF,sBAAO;gCACL,EAAE,EAAE,KAAK;gCACT,MAAM,EAAE,CAAC;gCACT,IAAI,EAAE,EAAE;gCACR,GAAG,EAAE,KAAG;6BACT,EAAA;;;;;KAEJ;IAED;;;OAGG;IACK,wCAAY,GAApB,UAAqB,GAAiB;QACpC,IAAI,GAAG,CAAC,GAAG,EAAE;YACX,OAAO,IAAI,CAAC;SACb;QACD,QAAQ,GAAG,CAAC,MAAM,EAAE;YAClB,KAAK,GAAG,CAAC,CAAC,UAAU;YACpB,KAAK,GAAG,CAAC,CAAC,YAAY;YACtB,KAAK,GAAG,CAAC,CAAC,oBAAoB;YAC9B,KAAK,GAAG,CAAC,CAAC,yBAAyB;YACnC,KAAK,GAAG,CAAC,CAAC,4BAA4B;YACtC,KAAK,GAAG,CAAC,CAAC,sBAAsB;YAChC,KAAK,GAAG,CAAC,CAAC,kBAAkB;YAC5B,KAAK,GAAG,EAAE,yBAAyB;gBACjC,OAAO,IAAI,CAAC;YACd;gBACE,OAAO,KAAK,CAAC;SAChB;IACH,CAAC;IAED;;OAEG;IACK,uCAAW,GAAnB,UAAoB,OAAuB;QACzC,sCACK,IAAI,CAAC,OAAO,GACZ,OAAO,KACV,OAAO,wBACF,IAAI,CAAC,OAAO,CAAC,OAAO,GACpB,OAAO,CAAC,OAAO,KAEpB;IACJ,CAAC;IAED;;OAEG;IACO,mCAAO,GAAjB,UACE,OAAe,EACf,IAAY,EACZ,MAAc,EACd,KAAa,EACb,IAAS,EACT,OAA8C;QAA9C,wBAAA,EAAA,YAA8C;QAE9C,IAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;QAC3E,OAAO,IAAI,eAAe,CAAC,OAAO,CAAC,CAAC;IACtC,CAAC;IAED;;;OAGG;IACW,oCAAQ,GAAtB,UACE,OAAe,EACf,IAAY,EACZ,MAAc,EACd,KAAa,EACb,IAAS,EACT,OAA8C;;QAA9C,wBAAA,EAAA,YAA8C;;;;;;wBAE9C,OAAO,GAAG,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;wBAC9B,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,OAAO,EAAE,MAAA,OAAO,CAAC,KAAK,mCAAI,EAAE,CAAC,CAAC;wBAC1D,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC;4BAC5B,YAAY,EAAE,mBAAmB;yBAClC,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;wBACpB,IAAI,OAAO,CAAC,KAAK,EAAE;4BACjB,OAAO,CAAC,eAAe,CAAC,GAAG,YAAU,OAAO,CAAC,KAAO,CAAC;yBACtD;wBACK,GAAG,GAAgB,EAAE,IAAI,MAAA,EAAE,OAAO,SAAA,EAAE,GAAG,KAAA,EAAE,MAAM,QAAA,EAAE,OAAO,SAAA,EAAE,CAAC;wBACjE,IAAI,IAAI,EAAE;4BACR,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;yBACjC;wBACD,IAAI,OAAO,CAAC,KAAK,EAAE;4BACjB,OAAO,CAAC,GAAG,CAAC,SAAO,MAAM,CAAC,WAAW,EAAE,MAAG,EAAE,GAAG,EAAE,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;yBAChF;wBACW,qBAAM,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,OAAO,CAAC,EAAA;;wBAApC,GAAG,GAAG,SAA8B;wBAC1C,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE;4BACL,GAAG,GAAG,YAAY,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;4BACvC,IAAI,OAAO,CAAC,KAAK,EAAE;gCACjB,OAAO,CAAC,GAAG,CAAC,SAAO,GAAG,CAAC,MAAM,MAAG,EAAE,GAAG,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;6BACrD;4BACD,IAAI,OAAO,OAAO,CAAC,KAAK,KAAK,QAAQ,IAAI,OAAO,CAAC,KAAK,GAAG,CAAC,IAAI,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,EAAE;gCACpF,OAAO,CAAC,KAAK,EAAE,CAAC;gCAChB,sBAAO,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,CAAC,EAAC;6BAClE;4BACD,MAAM,GAAG,CAAC;yBACX;wBACK,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC;wBACxD,IAAI,OAAO,CAAC,KAAK,EAAE;4BACjB,OAAO,CAAC,GAAG,CAAC,SAAO,GAAG,CAAC,MAAM,MAAG,EAAE,GAAG,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;yBACvE;wBACD,sBAAO,IAAI,EAAC;;;;KACb;IACH,wBAAC;AAAD,CAAC,AA5JD,IA4JC;AA5JqB,8CAAiB"}
|
package/package.json
CHANGED
package/src/base.ts
CHANGED
|
@@ -40,6 +40,7 @@ export interface ResponseData {
|
|
|
40
40
|
ok: boolean;
|
|
41
41
|
status: number;
|
|
42
42
|
body: string;
|
|
43
|
+
err?: any; // network error
|
|
43
44
|
}
|
|
44
45
|
|
|
45
46
|
/**
|
|
@@ -112,7 +113,7 @@ export class ResponsePromise<T> implements Promise<T> {
|
|
|
112
113
|
/**
|
|
113
114
|
* Either a response body or a service error.
|
|
114
115
|
*/
|
|
115
|
-
type EitherResponse<T> = { ok: true; data: T; err: null } | { ok: false; data: null, err: ServiceError; };
|
|
116
|
+
export type EitherResponse<T> = { ok: true; data: T; err: null } | { ok: false; data: null, err: ServiceError; };
|
|
116
117
|
|
|
117
118
|
/**
|
|
118
119
|
* This is a hack to make captureStackTrace visible.
|
|
@@ -210,13 +211,23 @@ export class ServiceError extends Error {
|
|
|
210
211
|
static from_res(res: ResponseData): ServiceError {
|
|
211
212
|
let message = res.body;
|
|
212
213
|
let code = res.status;
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
if (
|
|
216
|
-
|
|
217
|
-
|
|
214
|
+
if (res.err) {
|
|
215
|
+
// network error
|
|
216
|
+
if (res.err instanceof Error) {
|
|
217
|
+
message = res.err.message;
|
|
218
|
+
} else {
|
|
219
|
+
message = "Network Error";
|
|
218
220
|
}
|
|
219
|
-
|
|
221
|
+
code = 0;
|
|
222
|
+
} else {
|
|
223
|
+
try {
|
|
224
|
+
let data = JSON.parse(res.body);
|
|
225
|
+
if (data.code && (data.message || data.error)) {
|
|
226
|
+
code = data.code;
|
|
227
|
+
message = data.message || data.error;
|
|
228
|
+
}
|
|
229
|
+
} catch (_) {}
|
|
230
|
+
}
|
|
220
231
|
const err = new ServiceError(res.status, code, message);
|
|
221
232
|
// override the stack trace so that it doesn't include the from_res helper.
|
|
222
233
|
if (Error.captureStackTrace) {
|
|
@@ -268,23 +279,48 @@ export abstract class BaseServiceClient {
|
|
|
268
279
|
if (options?.intercept) {
|
|
269
280
|
return options.intercept(req, this.fetch.bind(this));
|
|
270
281
|
}
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
282
|
+
try {
|
|
283
|
+
const res = await fetch(req.url, {
|
|
284
|
+
method: req.method,
|
|
285
|
+
body: req.body,
|
|
286
|
+
headers: req.headers,
|
|
287
|
+
});
|
|
288
|
+
return {
|
|
289
|
+
ok: res.ok,
|
|
290
|
+
status: res.status,
|
|
291
|
+
body: await res.text(),
|
|
292
|
+
};
|
|
293
|
+
} catch (err) {
|
|
294
|
+
return {
|
|
295
|
+
ok: false,
|
|
296
|
+
status: 0,
|
|
297
|
+
body: "",
|
|
298
|
+
err: err,
|
|
299
|
+
}
|
|
300
|
+
}
|
|
281
301
|
}
|
|
282
302
|
|
|
283
303
|
/**
|
|
284
|
-
* Returns true if the
|
|
304
|
+
* Returns true if the status code represents a transient error
|
|
305
|
+
* or it's a network error.
|
|
285
306
|
*/
|
|
286
|
-
private
|
|
287
|
-
|
|
307
|
+
private should_retry(res: ResponseData): boolean {
|
|
308
|
+
if (res.err) {
|
|
309
|
+
return true;
|
|
310
|
+
}
|
|
311
|
+
switch (res.status) {
|
|
312
|
+
case 408: // timeout
|
|
313
|
+
case 413: // too large
|
|
314
|
+
case 429: // too many requests
|
|
315
|
+
case 500: // generic error response
|
|
316
|
+
case 502: // invalid upstream response
|
|
317
|
+
case 503: // service unavailable
|
|
318
|
+
case 504: // gateway timeout
|
|
319
|
+
case 522: // tcp connection timeout
|
|
320
|
+
return true;
|
|
321
|
+
default:
|
|
322
|
+
return false;
|
|
323
|
+
}
|
|
288
324
|
}
|
|
289
325
|
|
|
290
326
|
/**
|
|
@@ -349,7 +385,7 @@ export abstract class BaseServiceClient {
|
|
|
349
385
|
if (options.debug) {
|
|
350
386
|
console.log(`ERR(${res.status})`, url, err.message);
|
|
351
387
|
}
|
|
352
|
-
if (typeof options.retry === "number" && options.retry > 0 &&
|
|
388
|
+
if (typeof options.retry === "number" && options.retry > 0 && this.should_retry(res)) {
|
|
353
389
|
options.retry--;
|
|
354
390
|
return this.request(service, name, method, route, body, options);
|
|
355
391
|
}
|
package/test/client.test.ts
CHANGED
|
@@ -4,16 +4,19 @@ import { Task } from "../src/interface/task";
|
|
|
4
4
|
|
|
5
5
|
describe("ServiceClient", () => {
|
|
6
6
|
|
|
7
|
-
function response(status: number, body?: any): ResponseData {
|
|
8
|
-
const res = { ok: status === 200, status: status, body: "" };
|
|
7
|
+
function response(status: number, body?: any, err?: any): ResponseData {
|
|
8
|
+
const res = { ok: status === 200, status: status, body: "", err: undefined };
|
|
9
9
|
if (body) {
|
|
10
10
|
res.body = JSON.stringify(body);
|
|
11
11
|
}
|
|
12
|
+
if (err) {
|
|
13
|
+
res.err = err;
|
|
14
|
+
}
|
|
12
15
|
return res;
|
|
13
16
|
}
|
|
14
17
|
|
|
15
|
-
function interceptor(status: number, body?: any): InterceptFn {
|
|
16
|
-
return (req: RequestData) => Promise.resolve(response(status, body));
|
|
18
|
+
function interceptor(status: number, body?: any, err?: any): InterceptFn {
|
|
19
|
+
return (req: RequestData) => Promise.resolve(response(status, body, err));
|
|
17
20
|
}
|
|
18
21
|
|
|
19
22
|
test("makes basic request", async () => {
|
|
@@ -67,7 +70,7 @@ describe("ServiceClient", () => {
|
|
|
67
70
|
});
|
|
68
71
|
});
|
|
69
72
|
|
|
70
|
-
test("client retries on
|
|
73
|
+
test("client retries on bad status codes", async () => {
|
|
71
74
|
const intercept = jest.fn(async (req: RequestData) => {
|
|
72
75
|
if (intercept.mock.calls.length === 3) {
|
|
73
76
|
return response(200, "{}");
|
|
@@ -79,6 +82,18 @@ describe("ServiceClient", () => {
|
|
|
79
82
|
expect(intercept.mock.calls.length).toBe(3);
|
|
80
83
|
});
|
|
81
84
|
|
|
85
|
+
test("client retries on network error", async () => {
|
|
86
|
+
const intercept = jest.fn(async (req: RequestData) => {
|
|
87
|
+
if (intercept.mock.calls.length === 3) {
|
|
88
|
+
return response(200, "{}");
|
|
89
|
+
}
|
|
90
|
+
return response(0, "", new Error("network error"));
|
|
91
|
+
});
|
|
92
|
+
const api = new ServiceClient({ intercept });
|
|
93
|
+
const task = await api.get_task("", { retry: 2 });
|
|
94
|
+
expect(intercept.mock.calls.length).toBe(3);
|
|
95
|
+
});
|
|
96
|
+
|
|
82
97
|
test("client gives up after retry limit", async () => {
|
|
83
98
|
const intercept = jest.fn(interceptor(500));
|
|
84
99
|
const api = new ServiceClient({ intercept });
|
|
@@ -124,6 +139,19 @@ describe("ServiceClient", () => {
|
|
|
124
139
|
}
|
|
125
140
|
});
|
|
126
141
|
|
|
142
|
+
test("throws ServiceError for network errors", async () => {
|
|
143
|
+
const api = new ServiceClient({
|
|
144
|
+
intercept: interceptor(0, null, new Error("Network Error")),
|
|
145
|
+
});
|
|
146
|
+
try {
|
|
147
|
+
await api.get_task("");
|
|
148
|
+
} catch (err) {
|
|
149
|
+
expect(err).toBeInstanceOf(ServiceError);
|
|
150
|
+
expect(ServiceError.status(err)).toBe(0);
|
|
151
|
+
expect(ServiceError.code(err)).toBe(0);
|
|
152
|
+
}
|
|
153
|
+
});
|
|
154
|
+
|
|
127
155
|
test("either should be true with 200 response", async () => {
|
|
128
156
|
const api = new ServiceClient({
|
|
129
157
|
intercept: interceptor(200, "{}"),
|