@larksuiteoapi/node-sdk 1.62.2 → 1.63.1

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/es/index.js CHANGED
@@ -85418,10 +85418,16 @@ class WSClient {
85418
85418
  timeout: 15000,
85419
85419
  });
85420
85420
  if (code !== ErrorCode.ok) {
85421
- this.logger.error('[ws]', `code: ${code}, ${code === ErrorCode.system_busy ? msg : 'system busy'}`);
85422
- if (code === ErrorCode.system_busy || code === ErrorCode.internal_error) {
85423
- return false;
85421
+ const reason = code === ErrorCode.system_busy ? 'system busy' : msg;
85422
+ this.logger.error('[ws]', `code: ${code}, ${reason}`);
85423
+ if (code === ErrorCode.internal_error) {
85424
+ return { ok: false, retryable: true };
85424
85425
  }
85426
+ return {
85427
+ ok: false,
85428
+ retryable: false,
85429
+ error: `pullConnectConfig failed: code=${code}, msg=${reason}`,
85430
+ };
85425
85431
  }
85426
85432
  const { device_id, service_id } = qs.parse(URL);
85427
85433
  this.wsConfig.updateWs({
@@ -85434,11 +85440,11 @@ class WSClient {
85434
85440
  reconnectNonce: ClientConfig.ReconnectNonce * 1000
85435
85441
  });
85436
85442
  this.logger.debug('[ws]', `get connect config success, ws url: ${URL}`);
85437
- return true;
85443
+ return { ok: true };
85438
85444
  }
85439
85445
  catch (e) {
85440
85446
  this.logger.error('[ws]', (e === null || e === void 0 ? void 0 : e.message) || 'system busy');
85441
- return false;
85447
+ return { ok: false, retryable: true };
85442
85448
  }
85443
85449
  });
85444
85450
  }
@@ -85477,18 +85483,17 @@ class WSClient {
85477
85483
  this.isConnecting = true;
85478
85484
  // Invalidate any in-flight reconnect loops from previous sessions
85479
85485
  const currentGeneration = ++this.reconnectGeneration;
85480
- const tryConnect = () => {
85486
+ const tryConnect = () => __awaiter(this, void 0, void 0, function* () {
85481
85487
  this.reconnectInfo.lastConnectTime = Date.now();
85482
- return this.pullConnectConfig()
85483
- .then(isSuccess => isSuccess ? this.connect() : Promise.resolve(false))
85484
- .then(isSuccess => {
85485
- if (isSuccess) {
85486
- this.communicate();
85487
- return Promise.resolve(true);
85488
- }
85489
- return Promise.resolve(false);
85490
- });
85491
- };
85488
+ const pullResult = yield this.pullConnectConfig();
85489
+ if (!pullResult.ok)
85490
+ return pullResult;
85491
+ const connected = yield this.connect();
85492
+ if (!connected)
85493
+ return { ok: false, retryable: true };
85494
+ this.communicate();
85495
+ return { ok: true };
85496
+ });
85492
85497
  if (this.pingInterval) {
85493
85498
  clearTimeout(this.pingInterval);
85494
85499
  }
@@ -85500,17 +85505,25 @@ class WSClient {
85500
85505
  if (wsInstance) {
85501
85506
  wsInstance === null || wsInstance === void 0 ? void 0 : wsInstance.terminate();
85502
85507
  }
85503
- let isSuccess = false;
85508
+ let result = { ok: false, retryable: true };
85504
85509
  try {
85505
- isSuccess = yield tryConnect();
85510
+ result = yield tryConnect();
85506
85511
  }
85507
85512
  finally {
85508
85513
  this.isConnecting = false;
85509
85514
  }
85510
- if (isSuccess) {
85515
+ if (result.ok) {
85511
85516
  this.hasEverConnected = true;
85512
85517
  this.safeInvoke('onReady', this.onReady);
85513
85518
  }
85519
+ else if (!result.retryable) {
85520
+ // Non-recoverable error from pullConnectConfig — bail out without retry.
85521
+ // Reset hasEverConnected so a subsequent start() is treated as a fresh
85522
+ // session (onReady fires, not onReconnected).
85523
+ this.hasEverConnected = false;
85524
+ this.safeInvoke('onError', this.onError, new Error(result.error));
85525
+ return;
85526
+ }
85514
85527
  else {
85515
85528
  this.logger.error('[ws]', 'connect failed');
85516
85529
  yield this.reConnect();
@@ -85542,13 +85555,13 @@ class WSClient {
85542
85555
  return;
85543
85556
  }
85544
85557
  count++;
85545
- const isSuccess = yield tryConnect();
85558
+ const result = yield tryConnect();
85546
85559
  // Re-check after async operation in case a new session started
85547
85560
  if (currentGeneration !== this.reconnectGeneration) {
85548
85561
  return;
85549
85562
  }
85550
85563
  // if reconnectCount < 0, the reconnect time is infinite
85551
- if (isSuccess) {
85564
+ if (result.ok) {
85552
85565
  this.logger.debug('[ws]', 'reconnect success');
85553
85566
  if (this.hasEverConnected) {
85554
85567
  this.safeInvoke('onReconnected', this.onReconnected);
@@ -85560,6 +85573,15 @@ class WSClient {
85560
85573
  this.isConnecting = false;
85561
85574
  return;
85562
85575
  }
85576
+ if (!result.retryable) {
85577
+ // Non-recoverable error — abort the loop, do not schedule another attempt.
85578
+ // Reset hasEverConnected so a subsequent start() is treated as a fresh
85579
+ // session (onReady fires, not onReconnected).
85580
+ this.isConnecting = false;
85581
+ this.hasEverConnected = false;
85582
+ this.safeInvoke('onError', this.onError, new Error(result.error));
85583
+ return;
85584
+ }
85563
85585
  this.logger.info('ws', `unable to connect to the server after trying ${count} times")`);
85564
85586
  if (reconnectCount >= 0 && count >= reconnectCount) {
85565
85587
  this.isConnecting = false;
@@ -85726,19 +85748,24 @@ class WSClient {
85726
85748
  }
85727
85749
  start(params) {
85728
85750
  return __awaiter(this, void 0, void 0, function* () {
85729
- this.logger.info('[ws]', `receive events or callbacks through persistent connection only available in self-build & Feishu app, Configured in:
85730
- Developer Console(开发者后台)
85731
- ->
85732
- Events and Callbacks(事件与回调)
85733
- ->
85734
- Mode of event/callback subscription(订阅方式)
85735
- ->
85736
- Receive events/callbacks through persistent connection(使用 长连接 接收事件/回调)`);
85751
+ const { appId } = this.wsConfig.getClient();
85752
+ if (!/^cli_[0-9a-fA-F]{16}$/.test(appId)) {
85753
+ this.logger.error('[ws]', `invalid appId: ${appId}`);
85754
+ return;
85755
+ }
85737
85756
  const { eventDispatcher } = params;
85738
85757
  if (!eventDispatcher) {
85739
85758
  this.logger.warn('[ws]', 'client need to start with a eventDispatcher');
85740
85759
  return;
85741
85760
  }
85761
+ this.logger.info('[ws]', `receive events or callbacks through persistent connection only available in self-build & Feishu app, Configured in:
85762
+ Developer Console(开发者后台)
85763
+ ->
85764
+ Events and Callbacks(事件与回调)
85765
+ ->
85766
+ Mode of event/callback subscription(订阅方式)
85767
+ ->
85768
+ Receive events/callbacks through persistent connection(使用 长连接 接收事件/回调)`);
85742
85769
  this.eventDispatcher = eventDispatcher;
85743
85770
  this.reConnect(true);
85744
85771
  });
package/lib/index.js CHANGED
@@ -85436,10 +85436,16 @@ class WSClient {
85436
85436
  timeout: 15000,
85437
85437
  });
85438
85438
  if (code !== ErrorCode.ok) {
85439
- this.logger.error('[ws]', `code: ${code}, ${code === ErrorCode.system_busy ? msg : 'system busy'}`);
85440
- if (code === ErrorCode.system_busy || code === ErrorCode.internal_error) {
85441
- return false;
85439
+ const reason = code === ErrorCode.system_busy ? 'system busy' : msg;
85440
+ this.logger.error('[ws]', `code: ${code}, ${reason}`);
85441
+ if (code === ErrorCode.internal_error) {
85442
+ return { ok: false, retryable: true };
85442
85443
  }
85444
+ return {
85445
+ ok: false,
85446
+ retryable: false,
85447
+ error: `pullConnectConfig failed: code=${code}, msg=${reason}`,
85448
+ };
85443
85449
  }
85444
85450
  const { device_id, service_id } = qs__default["default"].parse(URL);
85445
85451
  this.wsConfig.updateWs({
@@ -85452,11 +85458,11 @@ class WSClient {
85452
85458
  reconnectNonce: ClientConfig.ReconnectNonce * 1000
85453
85459
  });
85454
85460
  this.logger.debug('[ws]', `get connect config success, ws url: ${URL}`);
85455
- return true;
85461
+ return { ok: true };
85456
85462
  }
85457
85463
  catch (e) {
85458
85464
  this.logger.error('[ws]', (e === null || e === void 0 ? void 0 : e.message) || 'system busy');
85459
- return false;
85465
+ return { ok: false, retryable: true };
85460
85466
  }
85461
85467
  });
85462
85468
  }
@@ -85495,18 +85501,17 @@ class WSClient {
85495
85501
  this.isConnecting = true;
85496
85502
  // Invalidate any in-flight reconnect loops from previous sessions
85497
85503
  const currentGeneration = ++this.reconnectGeneration;
85498
- const tryConnect = () => {
85504
+ const tryConnect = () => __awaiter(this, void 0, void 0, function* () {
85499
85505
  this.reconnectInfo.lastConnectTime = Date.now();
85500
- return this.pullConnectConfig()
85501
- .then(isSuccess => isSuccess ? this.connect() : Promise.resolve(false))
85502
- .then(isSuccess => {
85503
- if (isSuccess) {
85504
- this.communicate();
85505
- return Promise.resolve(true);
85506
- }
85507
- return Promise.resolve(false);
85508
- });
85509
- };
85506
+ const pullResult = yield this.pullConnectConfig();
85507
+ if (!pullResult.ok)
85508
+ return pullResult;
85509
+ const connected = yield this.connect();
85510
+ if (!connected)
85511
+ return { ok: false, retryable: true };
85512
+ this.communicate();
85513
+ return { ok: true };
85514
+ });
85510
85515
  if (this.pingInterval) {
85511
85516
  clearTimeout(this.pingInterval);
85512
85517
  }
@@ -85518,17 +85523,25 @@ class WSClient {
85518
85523
  if (wsInstance) {
85519
85524
  wsInstance === null || wsInstance === void 0 ? void 0 : wsInstance.terminate();
85520
85525
  }
85521
- let isSuccess = false;
85526
+ let result = { ok: false, retryable: true };
85522
85527
  try {
85523
- isSuccess = yield tryConnect();
85528
+ result = yield tryConnect();
85524
85529
  }
85525
85530
  finally {
85526
85531
  this.isConnecting = false;
85527
85532
  }
85528
- if (isSuccess) {
85533
+ if (result.ok) {
85529
85534
  this.hasEverConnected = true;
85530
85535
  this.safeInvoke('onReady', this.onReady);
85531
85536
  }
85537
+ else if (!result.retryable) {
85538
+ // Non-recoverable error from pullConnectConfig — bail out without retry.
85539
+ // Reset hasEverConnected so a subsequent start() is treated as a fresh
85540
+ // session (onReady fires, not onReconnected).
85541
+ this.hasEverConnected = false;
85542
+ this.safeInvoke('onError', this.onError, new Error(result.error));
85543
+ return;
85544
+ }
85532
85545
  else {
85533
85546
  this.logger.error('[ws]', 'connect failed');
85534
85547
  yield this.reConnect();
@@ -85560,13 +85573,13 @@ class WSClient {
85560
85573
  return;
85561
85574
  }
85562
85575
  count++;
85563
- const isSuccess = yield tryConnect();
85576
+ const result = yield tryConnect();
85564
85577
  // Re-check after async operation in case a new session started
85565
85578
  if (currentGeneration !== this.reconnectGeneration) {
85566
85579
  return;
85567
85580
  }
85568
85581
  // if reconnectCount < 0, the reconnect time is infinite
85569
- if (isSuccess) {
85582
+ if (result.ok) {
85570
85583
  this.logger.debug('[ws]', 'reconnect success');
85571
85584
  if (this.hasEverConnected) {
85572
85585
  this.safeInvoke('onReconnected', this.onReconnected);
@@ -85578,6 +85591,15 @@ class WSClient {
85578
85591
  this.isConnecting = false;
85579
85592
  return;
85580
85593
  }
85594
+ if (!result.retryable) {
85595
+ // Non-recoverable error — abort the loop, do not schedule another attempt.
85596
+ // Reset hasEverConnected so a subsequent start() is treated as a fresh
85597
+ // session (onReady fires, not onReconnected).
85598
+ this.isConnecting = false;
85599
+ this.hasEverConnected = false;
85600
+ this.safeInvoke('onError', this.onError, new Error(result.error));
85601
+ return;
85602
+ }
85581
85603
  this.logger.info('ws', `unable to connect to the server after trying ${count} times")`);
85582
85604
  if (reconnectCount >= 0 && count >= reconnectCount) {
85583
85605
  this.isConnecting = false;
@@ -85744,19 +85766,24 @@ class WSClient {
85744
85766
  }
85745
85767
  start(params) {
85746
85768
  return __awaiter(this, void 0, void 0, function* () {
85747
- this.logger.info('[ws]', `receive events or callbacks through persistent connection only available in self-build & Feishu app, Configured in:
85748
- Developer Console(开发者后台)
85749
- ->
85750
- Events and Callbacks(事件与回调)
85751
- ->
85752
- Mode of event/callback subscription(订阅方式)
85753
- ->
85754
- Receive events/callbacks through persistent connection(使用 长连接 接收事件/回调)`);
85769
+ const { appId } = this.wsConfig.getClient();
85770
+ if (!/^cli_[0-9a-fA-F]{16}$/.test(appId)) {
85771
+ this.logger.error('[ws]', `invalid appId: ${appId}`);
85772
+ return;
85773
+ }
85755
85774
  const { eventDispatcher } = params;
85756
85775
  if (!eventDispatcher) {
85757
85776
  this.logger.warn('[ws]', 'client need to start with a eventDispatcher');
85758
85777
  return;
85759
85778
  }
85779
+ this.logger.info('[ws]', `receive events or callbacks through persistent connection only available in self-build & Feishu app, Configured in:
85780
+ Developer Console(开发者后台)
85781
+ ->
85782
+ Events and Callbacks(事件与回调)
85783
+ ->
85784
+ Mode of event/callback subscription(订阅方式)
85785
+ ->
85786
+ Receive events/callbacks through persistent connection(使用 长连接 接收事件/回调)`);
85760
85787
  this.eventDispatcher = eventDispatcher;
85761
85788
  this.reConnect(true);
85762
85789
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@larksuiteoapi/node-sdk",
3
- "version": "1.62.2",
3
+ "version": "1.63.1",
4
4
  "description": "larksuite open sdk for nodejs",
5
5
  "keywords": [
6
6
  "feishu",
package/types/index.d.ts CHANGED
@@ -293069,6 +293069,7 @@ interface IConstructorParams {
293069
293069
  /** Fires after the reconnect loop successfully re-establishes the connection. */
293070
293070
  onReconnected?: () => void;
293071
293071
  }
293072
+
293072
293073
  declare class WSClient {
293073
293074
  private wsConfig;
293074
293075
  private logger;