@be-link/ecommerce-product-service-node-sdk 0.1.11 → 1.0.0

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@be-link/ecommerce-product-service-node-sdk",
3
- "version": "0.1.11",
3
+ "version": "1.0.0",
4
4
  "description": "EcommerceProductService Node.js SDK",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
@@ -11,8 +11,7 @@
11
11
  },
12
12
  "dependencies": {
13
13
  "@fastify/request-context": "6.2.1",
14
- "axios": "1.13.2",
15
- "axios-retry": "4.0.0",
14
+ "undici": "^6.0.0",
16
15
  "uuid": "9.0.1",
17
16
  "tsoa": "^6.6.0"
18
17
  },
package/utils/http.d.ts CHANGED
@@ -7,4 +7,4 @@ declare module '@fastify/request-context' {
7
7
  pandoraRoleId?: string;
8
8
  }
9
9
  }
10
- export declare function callApi<T extends (...args: any[]) => Promise<any>>(url: string, request?: Parameters<T>[0]): Promise<Awaited<ReturnType<T>>>;
10
+ export declare function callApi<T extends (...args: any[]) => Promise<any>>(url: string, requestData?: Parameters<T>[0]): Promise<Awaited<ReturnType<T>>>;
package/utils/http.js CHANGED
@@ -32,76 +32,98 @@ var __importStar = (this && this.__importStar) || (function () {
32
32
  return result;
33
33
  };
34
34
  })();
35
- var __importDefault = (this && this.__importDefault) || function (mod) {
36
- return (mod && mod.__esModule) ? mod : { "default": mod };
37
- };
38
35
  Object.defineProperty(exports, "__esModule", { value: true });
39
36
  exports.callApi = callApi;
40
- const axios_1 = __importDefault(require("axios"));
37
+ const undici_1 = require("undici");
41
38
  const uuid_1 = require("uuid");
42
- const axios_retry_1 = __importDefault(require("axios-retry"));
43
39
  const request_context_1 = require("@fastify/request-context");
44
- (0, axios_retry_1.default)(axios_1.default, {
45
- retries: 1,
46
- retryCondition(error) {
47
- return error.response?.status === 502;
48
- },
49
- retryDelay: (retryCount) => {
50
- console.info(`retryCount: ${retryCount}, retryDelay: ${retryCount * 500}`);
51
- return retryCount * 500;
52
- },
53
- onRetry(retryCount, error, requestConfig) {
54
- console.info(`retryCount: ${retryCount}, onRetry: ${error.message}, requestHeader: ${JSON.stringify(requestConfig.headers)}`);
55
- },
56
- });
57
- async function callApi(url, request) {
40
+ async function callApi(url, requestData) {
58
41
  const requestId = request_context_1.requestContext.get('requestId') || request_context_1.requestContext.get('traceMessageId') || (0, uuid_1.v4)();
59
42
  const pandoraUserId = request_context_1.requestContext.get('pandoraUserId') || '';
60
43
  const beLinkUserId = request_context_1.requestContext.get('beLinkUserId') || '';
61
44
  const pandoraRoleId = request_context_1.requestContext.get('pandoraRoleId') || '';
62
- try {
63
- console.info(`准备发起ecommerce-product-service请求[${requestId}]: ${url}, 参数: ${JSON.stringify(request)}`);
64
- const response = await axios_1.default.post(url, request || {}, {
65
- headers: {
66
- 'x-request-id': requestId,
67
- 'x-belink-pandora-userid': pandoraUserId,
68
- 'x-belink-userid': beLinkUserId,
69
- 'x-belink-pandora-roleid': pandoraRoleId,
70
- },
71
- });
72
- const responseData = response.data;
73
- return responseData.data;
74
- }
75
- catch (error) {
76
- const axiosError = error;
77
- if (axiosError.response) {
78
- const response = axiosError.response;
79
- const data = response.data;
80
- console.error(`ecommerce-product-service 异常: ${axiosError.message},requestId: ${requestId}`);
81
- console.info('响应信息', data.message);
82
- console.error('异常堆栈', JSON.stringify(error.stack));
83
- throw error;
84
- }
85
- // 调用dns模块解析url
86
- const dns = await Promise.resolve().then(() => __importStar(require('dns')));
87
- const dnsPromise = new Promise((resolve, reject) => {
88
- const lookupRes = dns.lookup(url, (err, address) => {
89
- if (err) {
90
- console.error(err.message);
91
- reject(err);
92
- }
93
- console.info(`lookup: ${JSON.stringify(lookupRes)}`);
94
- resolve(address);
95
- });
96
- });
45
+ // 重试配置
46
+ const maxRetries = 1;
47
+ let lastError = null;
48
+ for (let attempt = 0; attempt <= maxRetries; attempt++) {
97
49
  try {
98
- const address = await dnsPromise;
99
- console.info(`address: ${JSON.stringify(address)}`);
50
+ if (attempt > 0) {
51
+ const delay = attempt * 500;
52
+ console.info(`retryCount: ${attempt}, retryDelay: ${delay}`);
53
+ await new Promise((resolve) => setTimeout(resolve, delay));
54
+ }
55
+ console.info(`准备发起ecommerce-product-service请求[${requestId}]: ${url}, 参数: ${JSON.stringify(requestData)}`);
56
+ const response = await (0, undici_1.request)(url, {
57
+ method: 'POST',
58
+ headers: {
59
+ 'content-type': 'application/json',
60
+ 'x-request-id': requestId,
61
+ 'x-belink-pandora-userid': pandoraUserId,
62
+ 'x-belink-userid': beLinkUserId,
63
+ 'x-belink-pandora-roleid': pandoraRoleId,
64
+ },
65
+ body: JSON.stringify(requestData || {}),
66
+ // undici 会自动协商 HTTP/2 (如果服务端支持)
67
+ });
68
+ const responseData = (await response.body.json());
69
+ // 如果是 502 错误且还有重试次数,继续重试
70
+ if (response.statusCode === 502 && attempt < maxRetries) {
71
+ console.info(`retryCount: ${attempt + 1}, onRetry: Status 502, requestHeader: ${JSON.stringify(response.headers)}`);
72
+ lastError = new Error(`HTTP ${response.statusCode}: ${responseData.message || 'Bad Gateway'}`);
73
+ continue;
74
+ }
75
+ // 非 2xx 状态码抛出错误
76
+ if (response.statusCode < 200 || response.statusCode >= 300) {
77
+ console.error(`ecommerce-product-service 异常: HTTP ${response.statusCode},requestId: ${requestId}`);
78
+ console.info('响应信息', responseData.message);
79
+ const error = new Error(`HTTP ${response.statusCode}: ${responseData.message}`);
80
+ error.response = { status: response.statusCode, data: responseData };
81
+ throw error;
82
+ }
83
+ return responseData.data;
100
84
  }
101
85
  catch (error) {
102
- console.info(`error: ${JSON.stringify(error)}`);
86
+ lastError = error;
87
+ // 如果有响应数据,说明是业务错误,不重试
88
+ if (error.response) {
89
+ console.error(`ecommerce-product-service 异常: ${error.message},requestId: ${requestId}`);
90
+ if (error.response.data) {
91
+ console.info('响应信息', error.response.data.message);
92
+ }
93
+ console.error('异常堆栈', JSON.stringify(error.stack));
94
+ throw error;
95
+ }
96
+ // 502 错误重试
97
+ if (error.response?.status === 502 && attempt < maxRetries) {
98
+ console.info(`retryCount: ${attempt + 1}, onRetry: ${error.message}`);
99
+ continue;
100
+ }
101
+ // 最后一次尝试失败,执行 DNS 诊断
102
+ if (attempt === maxRetries) {
103
+ // 调用dns模块解析url
104
+ const dns = await Promise.resolve().then(() => __importStar(require('dns')));
105
+ const dnsPromise = new Promise((resolve, reject) => {
106
+ const lookupRes = dns.lookup(url, (err, address) => {
107
+ if (err) {
108
+ console.error(err.message);
109
+ reject(err);
110
+ }
111
+ console.info(`lookup: ${JSON.stringify(lookupRes)}`);
112
+ resolve(address);
113
+ });
114
+ });
115
+ try {
116
+ const address = await dnsPromise;
117
+ console.info(`address: ${JSON.stringify(address)}`);
118
+ }
119
+ catch (dnsError) {
120
+ console.info(`error: ${JSON.stringify(dnsError)}`);
121
+ }
122
+ console.error(`ecommerce-product-service 未知异常: ${error.message}`, error.stack);
123
+ throw error;
124
+ }
103
125
  }
104
- console.error(`ecommerce-product-service 未知异常: ${axiosError.message}`, error.stack);
105
- throw error;
106
126
  }
127
+ // 如果所有重试都失败
128
+ throw lastError || new Error('Request failed after retries');
107
129
  }