@tmsfe/tms-core 0.0.188 → 0.0.190
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/package.json +1 -1
- package/src/logger.ts +22 -0
- package/src/request.js +99 -22
package/package.json
CHANGED
package/src/logger.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @desc: 日志输出
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
const logger = wx.getLogManager({});
|
|
6
|
+
|
|
7
|
+
// 上报自定义事件
|
|
8
|
+
function reportEvent(eventName, eventData: { ext1?: unknown; ext2?: unknown; ext3?: unknown; } = {}) {
|
|
9
|
+
// 避免tmsAegisInst内部报错
|
|
10
|
+
try {
|
|
11
|
+
wx.tmsAegisInst?.reportEvent({
|
|
12
|
+
name: eventName,
|
|
13
|
+
...eventData,
|
|
14
|
+
});
|
|
15
|
+
} catch (e) {}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// eslint-disable-next-line import/no-anonymous-default-export
|
|
19
|
+
export default {
|
|
20
|
+
...logger,
|
|
21
|
+
reportEvent,
|
|
22
|
+
};
|
package/src/request.js
CHANGED
|
@@ -13,8 +13,9 @@ import { getEnvInfo, getAuthInfo } from './env';
|
|
|
13
13
|
import { safeJsonParse } from './objUtils';
|
|
14
14
|
import { encryptObjInit } from './encrypt/index';
|
|
15
15
|
import reporter from './report/index';
|
|
16
|
+
import logger from './logger';
|
|
16
17
|
|
|
17
|
-
const
|
|
18
|
+
const RETRY_WX_ERR_NOS = [600001, 600003, 5]; // 微信底层错误重试码 600001-微信cronet组件错误 600003-网络中断 5-接口超时
|
|
18
19
|
|
|
19
20
|
/**
|
|
20
21
|
* 用于序列化需要签名的参数
|
|
@@ -372,15 +373,109 @@ export default class Request {
|
|
|
372
373
|
* @param {object} header 自定义的请求头
|
|
373
374
|
* @returns {Promise} 接口返回结果
|
|
374
375
|
*/
|
|
375
|
-
async createRequestTask(path, param = {}, method = 'POST', header = {}
|
|
376
|
-
|
|
376
|
+
async createRequestTask(path, param = {}, method = 'POST', header = {}) {
|
|
377
|
+
try {
|
|
378
|
+
const res = await this.invokeRequest(path, param, method, header);
|
|
379
|
+
// format 业务errcode,用于判断是否做重试
|
|
380
|
+
const { errCode } = formatResErrCode(path, res.data);
|
|
381
|
+
// 处理token失效情况(errcode=35)
|
|
382
|
+
const needRetryLogin = errCode === 35 && isPathNeedRetryLogin(path);
|
|
383
|
+
if (needRetryLogin) {
|
|
384
|
+
// 调用runtime的login方法刷新token
|
|
385
|
+
await loginRefresh();
|
|
386
|
+
// 刷新后重试一次请求
|
|
387
|
+
return await this.invokeRequest(path, param, method, header);
|
|
388
|
+
}
|
|
389
|
+
return res;
|
|
390
|
+
} catch (err) {
|
|
391
|
+
// 微信系统errno:在重试码白名单内,重试
|
|
392
|
+
const { retryFlag, retryApiWhiteMap } = wx.tmsFlagMap || {};
|
|
393
|
+
const isWhiteApi = retryApiWhiteMap?.home === 'all' ? true : (retryApiWhiteMap?.home || []).includes(path);
|
|
394
|
+
const canRetry = errno => RETRY_WX_ERR_NOS.includes(errno) && isWhiteApi;
|
|
395
|
+
if (retryFlag && canRetry(err?.errno)) {
|
|
396
|
+
return await this.handleReTry(path, param, method, header, {
|
|
397
|
+
reportMsg: {
|
|
398
|
+
errno: err.errno,
|
|
399
|
+
errMsg: err.errMsg,
|
|
400
|
+
},
|
|
401
|
+
// maxRetryCount: 2, // 先立即重试一次,失败再延时重试一次
|
|
402
|
+
waitTime: 300, // 微信底层错误300ms后重试一次
|
|
403
|
+
isSuccess: retryRes => !canRetry(retryRes?.errno),
|
|
404
|
+
});
|
|
405
|
+
}
|
|
406
|
+
return Promise.reject(err);
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
// 执行重试
|
|
411
|
+
async handleReTry(path, param, method, header, options) {
|
|
412
|
+
const currentRetryCount = options.currentRetryCount ?? 0;
|
|
413
|
+
const maxRetry = options.maxRetryCount ?? 1;
|
|
414
|
+
const genReportParams = (others = {}) => ({
|
|
415
|
+
ext1: 'home',
|
|
416
|
+
ext2: path,
|
|
417
|
+
ext3: JSON.stringify({
|
|
418
|
+
...options.reportMsg,
|
|
419
|
+
retryCount: `${currentRetryCount + 1}/${maxRetry}`,
|
|
420
|
+
...others,
|
|
421
|
+
}),
|
|
422
|
+
});
|
|
423
|
+
|
|
424
|
+
// 执行单次重试
|
|
425
|
+
const executeRetry = async () => {
|
|
426
|
+
reporter.reportEvent('接口发起重试', genReportParams());
|
|
427
|
+
// 如果有等待时间则延迟
|
|
428
|
+
if (options.waitTime) {
|
|
429
|
+
await new Promise(resolve => setTimeout(resolve, options.waitTime));
|
|
430
|
+
}
|
|
431
|
+
try {
|
|
432
|
+
const retryRes = await this.invokeRequest(path, param, method, header);
|
|
433
|
+
const nextReportParams = genReportParams({
|
|
434
|
+
retryResErrno: retryRes?.errno,
|
|
435
|
+
retryResErrMsg: retryRes?.errMsg,
|
|
436
|
+
});
|
|
437
|
+
// 检查是否成功
|
|
438
|
+
const isSuccess = options.isSuccess?.(retryRes) ?? true;
|
|
439
|
+
if (isSuccess) {
|
|
440
|
+
reporter.reportEvent('接口重试成功', nextReportParams);
|
|
441
|
+
return retryRes;
|
|
442
|
+
}
|
|
443
|
+
reporter.reportEvent('接口重试失败', nextReportParams);
|
|
444
|
+
throw new Error('业务逻辑判断失败');
|
|
445
|
+
} catch (error) {
|
|
446
|
+
reporter.reportEvent('接口重试失败', genReportParams({
|
|
447
|
+
retryResErrMsg: error.errMsg,
|
|
448
|
+
retryResType: 'catch',
|
|
449
|
+
}));
|
|
450
|
+
throw error;
|
|
451
|
+
}
|
|
452
|
+
};
|
|
453
|
+
|
|
454
|
+
try {
|
|
455
|
+
return await executeRetry();
|
|
456
|
+
} catch (err) {
|
|
457
|
+
// 检查是否还可以重试
|
|
458
|
+
if (currentRetryCount < maxRetry - 1) {
|
|
459
|
+
return await this.handleReTry(path, param, method, header, {
|
|
460
|
+
...options,
|
|
461
|
+
currentRetryCount: currentRetryCount + 1,
|
|
462
|
+
waitTime: 300, // 后续重试默认300ms间隔
|
|
463
|
+
});
|
|
464
|
+
}
|
|
465
|
+
return Promise.reject(err);
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
// 执行请求
|
|
470
|
+
async invokeRequest(path, param = {}, method = 'POST', header = {}) {
|
|
471
|
+
// maplbs接口不需要token
|
|
377
472
|
const withAuth = path.includes('maplbs/ws') ? false : this.withAuth;
|
|
378
473
|
const requestParam = await composeParam(param, withAuth, this.baseParam);
|
|
379
474
|
const data = sign(requestParam, this.secretKey);
|
|
380
475
|
return new Promise((resolve, reject) => {
|
|
381
476
|
const requestTime = Date.now();
|
|
382
477
|
const printLog = (isSuccess, res) => {
|
|
383
|
-
|
|
478
|
+
// 埋点已经单独打日志了,接口请求数据日志太长影响分析
|
|
384
479
|
if (path.indexOf('basic/event/upload') !== -1) {
|
|
385
480
|
return;
|
|
386
481
|
}
|
|
@@ -416,24 +511,6 @@ export default class Request {
|
|
|
416
511
|
|
|
417
512
|
const success = async (res) => {
|
|
418
513
|
printLog(true, res.data);
|
|
419
|
-
// format 业务errcode,用于判断是否做重试
|
|
420
|
-
const { errCode } = formatResErrCode(path, res.data);
|
|
421
|
-
// 处理token失效情况(errcode=35)
|
|
422
|
-
const needRetryLogin = !hasRetry && errCode === 35 && isPathNeedRetryLogin(path);
|
|
423
|
-
if (needRetryLogin) {
|
|
424
|
-
try {
|
|
425
|
-
// 调用runtime的login方法刷新token
|
|
426
|
-
await loginRefresh();
|
|
427
|
-
// 刷新后重试请求
|
|
428
|
-
const retryRes = await this.createRequestTask(path, param, method, header, true);
|
|
429
|
-
resolve(retryRes);
|
|
430
|
-
return;
|
|
431
|
-
} catch (e) {
|
|
432
|
-
// 刷新token失败,直接返回原错误
|
|
433
|
-
resolve(res);
|
|
434
|
-
return;
|
|
435
|
-
}
|
|
436
|
-
}
|
|
437
514
|
resolve(res);
|
|
438
515
|
};
|
|
439
516
|
const fail = (err) => {
|