@zeewain/3d-avatar-sdk 2.1.1 → 2.1.2

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.
@@ -16,7 +16,7 @@
16
16
  "lint:all-fix": "npm run lint:fix && npm run lint:css-fix"
17
17
  },
18
18
  "dependencies": {
19
- "@zeewain/3d-avatar-sdk": "^2.1.1",
19
+ "@zeewain/3d-avatar-sdk": "^2.1.2",
20
20
  "core-js": "^3.8.3",
21
21
  "element-ui": "^2.15.13",
22
22
  "vue": "^2.6.14"
@@ -24,7 +24,7 @@
24
24
  "@element-plus/icons-vue": "^2.3.1",
25
25
  "@vueuse/core": "^13.5.0",
26
26
  "@vueuse/integrations": "^13.5.0",
27
- "@zeewain/3d-avatar-sdk": "^2.1.1",
27
+ "@zeewain/3d-avatar-sdk": "^2.1.2",
28
28
  "dayjs": "^1.11.13",
29
29
  "element-plus": "^2.10.4",
30
30
  "vite-plugin-html": "^3.2.2",
package/dist/index.d.ts CHANGED
@@ -577,7 +577,7 @@ declare class ZEEAvatarSDK {
577
577
  * SDK 版本号
578
578
  * @const {string} SDK_VERSION
579
579
  */
580
- declare const SDK_VERSION = "2.1.1";
580
+ declare const SDK_VERSION = "2.1.2";
581
581
 
582
582
  /**
583
583
  * Unity服务日志记录器接口
@@ -1048,7 +1048,7 @@ declare class BroadcastService extends UnityBaseService<BroadcastOperationType>
1048
1048
  * 处理任务错误
1049
1049
  * @param task - 播报任务
1050
1050
  * @param error - 错误对象
1051
- * @description 处理任务执行过程中的错误
1051
+ * @description 处理任务执行过程中的错误,防止重复触发错误回调
1052
1052
  * @private
1053
1053
  */
1054
1054
  private handleTaskError;
@@ -1103,6 +1103,25 @@ declare class BroadcastService extends UnityBaseService<BroadcastOperationType>
1103
1103
  * @private
1104
1104
  */
1105
1105
  private clearQueueProcessTimer;
1106
+ /**
1107
+ * 根据 HTTP 状态码创建对应的 SDKError
1108
+ * @param status - HTTP 状态码
1109
+ * @param statusText - HTTP 状态文本
1110
+ * @param taskId - 任务 ID(用于日志记录)
1111
+ * @returns SDKError 实例
1112
+ * @description 将 HTTP 错误状态码映射为对应的 SDKError
1113
+ * @private
1114
+ */
1115
+ private createHttpError;
1116
+ /**
1117
+ * 将任意错误转换为 SDKError
1118
+ * @param error - 原始错误对象
1119
+ * @param taskId - 任务 ID(用于日志记录)
1120
+ * @returns SDKError 实例
1121
+ * @description 统一将各种类型的错误转换为 SDKError,便于上层统一处理
1122
+ * @private
1123
+ */
1124
+ private convertToSDKError;
1106
1125
  }
1107
1126
 
1108
1127
  /**
package/dist/index.es5.js CHANGED
@@ -14210,7 +14210,7 @@ var ZEEAvatarSDKLib = (function (exports) {
14210
14210
  */
14211
14211
  BroadcastService.prototype.startTaskRequest = function (task) {
14212
14212
  return __awaiter(this, void 0, void 0, function () {
14213
- var apiUrl, requestBody;
14213
+ var apiUrl, requestBody, sdkError;
14214
14214
  var _this = this;
14215
14215
  var _a;
14216
14216
  return __generator(this, function (_b) {
@@ -14245,6 +14245,25 @@ var ZEEAvatarSDKLib = (function (exports) {
14245
14245
  body: JSON.stringify(requestBody),
14246
14246
  signal: task.controller.signal,
14247
14247
  openWhenHidden: true,
14248
+ /**
14249
+ * 连接建立时的回调,用于检查 HTTP 状态码
14250
+ * @param response - HTTP 响应对象
14251
+ * @throws {SDKError} 当 HTTP 状态码异常时抛出对应的 SDKError
14252
+ */
14253
+ onopen: function onopen(response) {
14254
+ return __awaiter(_this, void 0, void 0, function () {
14255
+ var error;
14256
+ return __generator(this, function (_a) {
14257
+ // 检查 HTTP 状态码,处理 401 token 过期等异常
14258
+ if (!response.ok) {
14259
+ error = this.createHttpError(response.status, response.statusText, task.id);
14260
+ this.handleTaskError(task, error);
14261
+ throw error;
14262
+ }
14263
+ return [2 /*return*/];
14264
+ });
14265
+ });
14266
+ },
14248
14267
  onmessage: function onmessage(event) {
14249
14268
  _this.handleTaskResponse(task, event.data);
14250
14269
  },
@@ -14252,12 +14271,15 @@ var ZEEAvatarSDKLib = (function (exports) {
14252
14271
  _this.handleTaskClose(task);
14253
14272
  },
14254
14273
  onerror: function onerror(error) {
14255
- _this.handleTaskError(task, error);
14256
- throw new Error("Task ".concat(task.id, " request failed: ").concat(error));
14274
+ // 将所有异常统一转换为 SDKError
14275
+ var sdkError = _this.convertToSDKError(error, task.id);
14276
+ _this.handleTaskError(task, sdkError);
14277
+ throw sdkError;
14257
14278
  }
14258
14279
  });
14259
14280
  } catch (error) {
14260
- this.handleTaskError(task, error);
14281
+ sdkError = this.convertToSDKError(error, task.id);
14282
+ this.handleTaskError(task, sdkError);
14261
14283
  }
14262
14284
  return [2 /*return*/];
14263
14285
  });
@@ -14356,15 +14378,19 @@ var ZEEAvatarSDKLib = (function (exports) {
14356
14378
  * 处理任务错误
14357
14379
  * @param task - 播报任务
14358
14380
  * @param error - 错误对象
14359
- * @description 处理任务执行过程中的错误
14381
+ * @description 处理任务执行过程中的错误,防止重复触发错误回调
14360
14382
  * @private
14361
14383
  */
14362
14384
  BroadcastService.prototype.handleTaskError = function (task, error) {
14363
14385
  var _a, _b;
14386
+ // 如果任务已经是失败或取消状态,不再重复处理,防止回调被多次触发
14387
+ if (task.status === BroadcastTaskStatus.FAILED || task.status === BroadcastTaskStatus.CANCELLED) {
14388
+ return;
14389
+ }
14364
14390
  task.status = BroadcastTaskStatus.FAILED;
14365
14391
  task.error = error;
14366
14392
  this.logger.error("Task failed - ".concat(task.id), error);
14367
- // 触发错误回调
14393
+ // 触发错误回调(只触发一次)
14368
14394
  (_b = (_a = this.callbacks).onError) === null || _b === void 0 ? void 0 : _b.call(_a, error);
14369
14395
  };
14370
14396
  /**
@@ -14508,6 +14534,74 @@ var ZEEAvatarSDKLib = (function (exports) {
14508
14534
  this.queueProcessTimer = null;
14509
14535
  }
14510
14536
  };
14537
+ /**
14538
+ * 根据 HTTP 状态码创建对应的 SDKError
14539
+ * @param status - HTTP 状态码
14540
+ * @param statusText - HTTP 状态文本
14541
+ * @param taskId - 任务 ID(用于日志记录)
14542
+ * @returns SDKError 实例
14543
+ * @description 将 HTTP 错误状态码映射为对应的 SDKError
14544
+ * @private
14545
+ */
14546
+ BroadcastService.prototype.createHttpError = function (status, statusText, taskId) {
14547
+ this.logger.warn("HTTP error occurred - Task: ".concat(taskId, ", Status: ").concat(status), {
14548
+ status: status,
14549
+ statusText: statusText
14550
+ });
14551
+ switch (status) {
14552
+ case 401:
14553
+ // Token 过期或未授权
14554
+ return new SDKError(exports.NetworkErrorCode.UNAUTHORIZED, "Token \u5DF2\u8FC7\u671F\u6216\u65E0\u6548\uFF0C\u8BF7\u91CD\u65B0\u6388\u6743 (HTTP ".concat(status, ")"));
14555
+ case 403:
14556
+ // 禁止访问
14557
+ return new SDKError(exports.NetworkErrorCode.UNAUTHORIZED, "\u65E0\u6743\u9650\u8BBF\u95EE\u8BE5\u8D44\u6E90 (HTTP ".concat(status, ")"));
14558
+ case 404:
14559
+ // 资源不存在
14560
+ return new SDKError(exports.NetworkErrorCode.SERVER_ERROR, "\u8BF7\u6C42\u7684\u8D44\u6E90\u4E0D\u5B58\u5728 (HTTP ".concat(status, ")"));
14561
+ case 500:
14562
+ case 502:
14563
+ case 503:
14564
+ case 504:
14565
+ // 服务器错误
14566
+ return new SDKError(exports.NetworkErrorCode.SERVER_ERROR, "\u670D\u52A1\u5668\u9519\u8BEF\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5 (HTTP ".concat(status, ")"));
14567
+ default:
14568
+ // 其他 HTTP 错误
14569
+ return new SDKError(exports.NetworkErrorCode.CONNECTION_FAILED, "\u7F51\u7EDC\u8BF7\u6C42\u5931\u8D25: ".concat(statusText || 'Unknown Error', " (HTTP ").concat(status, ")"));
14570
+ }
14571
+ };
14572
+ /**
14573
+ * 将任意错误转换为 SDKError
14574
+ * @param error - 原始错误对象
14575
+ * @param taskId - 任务 ID(用于日志记录)
14576
+ * @returns SDKError 实例
14577
+ * @description 统一将各种类型的错误转换为 SDKError,便于上层统一处理
14578
+ * @private
14579
+ */
14580
+ BroadcastService.prototype.convertToSDKError = function (error, taskId) {
14581
+ // 如果已经是 SDKError,直接返回
14582
+ if (error instanceof SDKError) {
14583
+ return error;
14584
+ }
14585
+ // 如果是普通 Error 对象
14586
+ if (error instanceof Error) {
14587
+ // 检查是否是网络相关的错误
14588
+ var errorMessage_1 = error.message.toLowerCase();
14589
+ if (errorMessage_1.includes('timeout') || errorMessage_1.includes('timed out')) {
14590
+ return new SDKError(exports.NetworkErrorCode.REQUEST_TIMEOUT, "\u8BF7\u6C42\u8D85\u65F6 - Task: ".concat(taskId), error);
14591
+ }
14592
+ if (errorMessage_1.includes('network') || errorMessage_1.includes('fetch') || errorMessage_1.includes('connection')) {
14593
+ return new SDKError(exports.NetworkErrorCode.CONNECTION_FAILED, "\u7F51\u7EDC\u8FDE\u63A5\u5931\u8D25 - Task: ".concat(taskId, ": ").concat(error.message), error);
14594
+ }
14595
+ if (errorMessage_1.includes('abort') || errorMessage_1.includes('cancel')) {
14596
+ return new SDKError(exports.OperationErrorCode.OPERATION_CANCELLED, "\u64CD\u4F5C\u5DF2\u53D6\u6D88 - Task: ".concat(taskId), error);
14597
+ }
14598
+ // 默认作为操作失败处理
14599
+ return new SDKError(exports.OperationErrorCode.OPERATION_FAILED, "\u64AD\u62A5\u4EFB\u52A1\u6267\u884C\u5931\u8D25 - Task: ".concat(taskId, ": ").concat(error.message), error);
14600
+ }
14601
+ // 如果是字符串或其他类型
14602
+ var errorMessage = String(error);
14603
+ return new SDKError(exports.OperationErrorCode.OPERATION_FAILED, "\u64AD\u62A5\u4EFB\u52A1\u6267\u884C\u5931\u8D25 - Task: ".concat(taskId, ": ").concat(errorMessage));
14604
+ };
14511
14605
  return BroadcastService;
14512
14606
  }(UnityBaseService);
14513
14607
 
@@ -14213,7 +14213,7 @@
14213
14213
  */
14214
14214
  BroadcastService.prototype.startTaskRequest = function (task) {
14215
14215
  return __awaiter(this, void 0, void 0, function () {
14216
- var apiUrl, requestBody;
14216
+ var apiUrl, requestBody, sdkError;
14217
14217
  var _this = this;
14218
14218
  var _a;
14219
14219
  return __generator(this, function (_b) {
@@ -14248,6 +14248,25 @@
14248
14248
  body: JSON.stringify(requestBody),
14249
14249
  signal: task.controller.signal,
14250
14250
  openWhenHidden: true,
14251
+ /**
14252
+ * 连接建立时的回调,用于检查 HTTP 状态码
14253
+ * @param response - HTTP 响应对象
14254
+ * @throws {SDKError} 当 HTTP 状态码异常时抛出对应的 SDKError
14255
+ */
14256
+ onopen: function onopen(response) {
14257
+ return __awaiter(_this, void 0, void 0, function () {
14258
+ var error;
14259
+ return __generator(this, function (_a) {
14260
+ // 检查 HTTP 状态码,处理 401 token 过期等异常
14261
+ if (!response.ok) {
14262
+ error = this.createHttpError(response.status, response.statusText, task.id);
14263
+ this.handleTaskError(task, error);
14264
+ throw error;
14265
+ }
14266
+ return [2 /*return*/];
14267
+ });
14268
+ });
14269
+ },
14251
14270
  onmessage: function onmessage(event) {
14252
14271
  _this.handleTaskResponse(task, event.data);
14253
14272
  },
@@ -14255,12 +14274,15 @@
14255
14274
  _this.handleTaskClose(task);
14256
14275
  },
14257
14276
  onerror: function onerror(error) {
14258
- _this.handleTaskError(task, error);
14259
- throw new Error("Task ".concat(task.id, " request failed: ").concat(error));
14277
+ // 将所有异常统一转换为 SDKError
14278
+ var sdkError = _this.convertToSDKError(error, task.id);
14279
+ _this.handleTaskError(task, sdkError);
14280
+ throw sdkError;
14260
14281
  }
14261
14282
  });
14262
14283
  } catch (error) {
14263
- this.handleTaskError(task, error);
14284
+ sdkError = this.convertToSDKError(error, task.id);
14285
+ this.handleTaskError(task, sdkError);
14264
14286
  }
14265
14287
  return [2 /*return*/];
14266
14288
  });
@@ -14359,15 +14381,19 @@
14359
14381
  * 处理任务错误
14360
14382
  * @param task - 播报任务
14361
14383
  * @param error - 错误对象
14362
- * @description 处理任务执行过程中的错误
14384
+ * @description 处理任务执行过程中的错误,防止重复触发错误回调
14363
14385
  * @private
14364
14386
  */
14365
14387
  BroadcastService.prototype.handleTaskError = function (task, error) {
14366
14388
  var _a, _b;
14389
+ // 如果任务已经是失败或取消状态,不再重复处理,防止回调被多次触发
14390
+ if (task.status === BroadcastTaskStatus.FAILED || task.status === BroadcastTaskStatus.CANCELLED) {
14391
+ return;
14392
+ }
14367
14393
  task.status = BroadcastTaskStatus.FAILED;
14368
14394
  task.error = error;
14369
14395
  this.logger.error("Task failed - ".concat(task.id), error);
14370
- // 触发错误回调
14396
+ // 触发错误回调(只触发一次)
14371
14397
  (_b = (_a = this.callbacks).onError) === null || _b === void 0 ? void 0 : _b.call(_a, error);
14372
14398
  };
14373
14399
  /**
@@ -14511,6 +14537,74 @@
14511
14537
  this.queueProcessTimer = null;
14512
14538
  }
14513
14539
  };
14540
+ /**
14541
+ * 根据 HTTP 状态码创建对应的 SDKError
14542
+ * @param status - HTTP 状态码
14543
+ * @param statusText - HTTP 状态文本
14544
+ * @param taskId - 任务 ID(用于日志记录)
14545
+ * @returns SDKError 实例
14546
+ * @description 将 HTTP 错误状态码映射为对应的 SDKError
14547
+ * @private
14548
+ */
14549
+ BroadcastService.prototype.createHttpError = function (status, statusText, taskId) {
14550
+ this.logger.warn("HTTP error occurred - Task: ".concat(taskId, ", Status: ").concat(status), {
14551
+ status: status,
14552
+ statusText: statusText
14553
+ });
14554
+ switch (status) {
14555
+ case 401:
14556
+ // Token 过期或未授权
14557
+ return new SDKError(exports.NetworkErrorCode.UNAUTHORIZED, "Token \u5DF2\u8FC7\u671F\u6216\u65E0\u6548\uFF0C\u8BF7\u91CD\u65B0\u6388\u6743 (HTTP ".concat(status, ")"));
14558
+ case 403:
14559
+ // 禁止访问
14560
+ return new SDKError(exports.NetworkErrorCode.UNAUTHORIZED, "\u65E0\u6743\u9650\u8BBF\u95EE\u8BE5\u8D44\u6E90 (HTTP ".concat(status, ")"));
14561
+ case 404:
14562
+ // 资源不存在
14563
+ return new SDKError(exports.NetworkErrorCode.SERVER_ERROR, "\u8BF7\u6C42\u7684\u8D44\u6E90\u4E0D\u5B58\u5728 (HTTP ".concat(status, ")"));
14564
+ case 500:
14565
+ case 502:
14566
+ case 503:
14567
+ case 504:
14568
+ // 服务器错误
14569
+ return new SDKError(exports.NetworkErrorCode.SERVER_ERROR, "\u670D\u52A1\u5668\u9519\u8BEF\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5 (HTTP ".concat(status, ")"));
14570
+ default:
14571
+ // 其他 HTTP 错误
14572
+ return new SDKError(exports.NetworkErrorCode.CONNECTION_FAILED, "\u7F51\u7EDC\u8BF7\u6C42\u5931\u8D25: ".concat(statusText || 'Unknown Error', " (HTTP ").concat(status, ")"));
14573
+ }
14574
+ };
14575
+ /**
14576
+ * 将任意错误转换为 SDKError
14577
+ * @param error - 原始错误对象
14578
+ * @param taskId - 任务 ID(用于日志记录)
14579
+ * @returns SDKError 实例
14580
+ * @description 统一将各种类型的错误转换为 SDKError,便于上层统一处理
14581
+ * @private
14582
+ */
14583
+ BroadcastService.prototype.convertToSDKError = function (error, taskId) {
14584
+ // 如果已经是 SDKError,直接返回
14585
+ if (error instanceof SDKError) {
14586
+ return error;
14587
+ }
14588
+ // 如果是普通 Error 对象
14589
+ if (error instanceof Error) {
14590
+ // 检查是否是网络相关的错误
14591
+ var errorMessage_1 = error.message.toLowerCase();
14592
+ if (errorMessage_1.includes('timeout') || errorMessage_1.includes('timed out')) {
14593
+ return new SDKError(exports.NetworkErrorCode.REQUEST_TIMEOUT, "\u8BF7\u6C42\u8D85\u65F6 - Task: ".concat(taskId), error);
14594
+ }
14595
+ if (errorMessage_1.includes('network') || errorMessage_1.includes('fetch') || errorMessage_1.includes('connection')) {
14596
+ return new SDKError(exports.NetworkErrorCode.CONNECTION_FAILED, "\u7F51\u7EDC\u8FDE\u63A5\u5931\u8D25 - Task: ".concat(taskId, ": ").concat(error.message), error);
14597
+ }
14598
+ if (errorMessage_1.includes('abort') || errorMessage_1.includes('cancel')) {
14599
+ return new SDKError(exports.OperationErrorCode.OPERATION_CANCELLED, "\u64CD\u4F5C\u5DF2\u53D6\u6D88 - Task: ".concat(taskId), error);
14600
+ }
14601
+ // 默认作为操作失败处理
14602
+ return new SDKError(exports.OperationErrorCode.OPERATION_FAILED, "\u64AD\u62A5\u4EFB\u52A1\u6267\u884C\u5931\u8D25 - Task: ".concat(taskId, ": ").concat(error.message), error);
14603
+ }
14604
+ // 如果是字符串或其他类型
14605
+ var errorMessage = String(error);
14606
+ return new SDKError(exports.OperationErrorCode.OPERATION_FAILED, "\u64AD\u62A5\u4EFB\u52A1\u6267\u884C\u5931\u8D25 - Task: ".concat(taskId, ": ").concat(errorMessage));
14607
+ };
14514
14608
  return BroadcastService;
14515
14609
  }(UnityBaseService);
14516
14610
 
package/dist/index.esm.js CHANGED
@@ -1915,6 +1915,19 @@ class BroadcastService extends UnityBaseService {
1915
1915
  body: JSON.stringify(requestBody),
1916
1916
  signal: task.controller.signal,
1917
1917
  openWhenHidden: true,
1918
+ /**
1919
+ * 连接建立时的回调,用于检查 HTTP 状态码
1920
+ * @param response - HTTP 响应对象
1921
+ * @throws {SDKError} 当 HTTP 状态码异常时抛出对应的 SDKError
1922
+ */
1923
+ onopen: (response) => __awaiter(this, void 0, void 0, function* () {
1924
+ // 检查 HTTP 状态码,处理 401 token 过期等异常
1925
+ if (!response.ok) {
1926
+ const error = this.createHttpError(response.status, response.statusText, task.id);
1927
+ this.handleTaskError(task, error);
1928
+ throw error;
1929
+ }
1930
+ }),
1918
1931
  onmessage: (event) => {
1919
1932
  this.handleTaskResponse(task, event.data);
1920
1933
  },
@@ -1922,13 +1935,17 @@ class BroadcastService extends UnityBaseService {
1922
1935
  this.handleTaskClose(task);
1923
1936
  },
1924
1937
  onerror: (error) => {
1925
- this.handleTaskError(task, error);
1926
- throw new Error(`Task ${task.id} request failed: ${error}`);
1938
+ // 将所有异常统一转换为 SDKError
1939
+ const sdkError = this.convertToSDKError(error, task.id);
1940
+ this.handleTaskError(task, sdkError);
1941
+ throw sdkError;
1927
1942
  }
1928
1943
  });
1929
1944
  }
1930
1945
  catch (error) {
1931
- this.handleTaskError(task, error);
1946
+ // 将所有异常统一转换为 SDKError
1947
+ const sdkError = this.convertToSDKError(error, task.id);
1948
+ this.handleTaskError(task, sdkError);
1932
1949
  }
1933
1950
  });
1934
1951
  }
@@ -2016,15 +2033,19 @@ class BroadcastService extends UnityBaseService {
2016
2033
  * 处理任务错误
2017
2034
  * @param task - 播报任务
2018
2035
  * @param error - 错误对象
2019
- * @description 处理任务执行过程中的错误
2036
+ * @description 处理任务执行过程中的错误,防止重复触发错误回调
2020
2037
  * @private
2021
2038
  */
2022
2039
  handleTaskError(task, error) {
2023
2040
  var _a, _b;
2041
+ // 如果任务已经是失败或取消状态,不再重复处理,防止回调被多次触发
2042
+ if (task.status === BroadcastTaskStatus.FAILED || task.status === BroadcastTaskStatus.CANCELLED) {
2043
+ return;
2044
+ }
2024
2045
  task.status = BroadcastTaskStatus.FAILED;
2025
2046
  task.error = error;
2026
2047
  this.logger.error(`Task failed - ${task.id}`, error);
2027
- // 触发错误回调
2048
+ // 触发错误回调(只触发一次)
2028
2049
  (_b = (_a = this.callbacks).onError) === null || _b === void 0 ? void 0 : _b.call(_a, error);
2029
2050
  }
2030
2051
  /**
@@ -2148,6 +2169,71 @@ class BroadcastService extends UnityBaseService {
2148
2169
  this.queueProcessTimer = null;
2149
2170
  }
2150
2171
  }
2172
+ /**
2173
+ * 根据 HTTP 状态码创建对应的 SDKError
2174
+ * @param status - HTTP 状态码
2175
+ * @param statusText - HTTP 状态文本
2176
+ * @param taskId - 任务 ID(用于日志记录)
2177
+ * @returns SDKError 实例
2178
+ * @description 将 HTTP 错误状态码映射为对应的 SDKError
2179
+ * @private
2180
+ */
2181
+ createHttpError(status, statusText, taskId) {
2182
+ this.logger.warn(`HTTP error occurred - Task: ${taskId}, Status: ${status}`, { status, statusText });
2183
+ switch (status) {
2184
+ case 401:
2185
+ // Token 过期或未授权
2186
+ return new SDKError(NetworkErrorCode.UNAUTHORIZED, `Token 已过期或无效,请重新授权 (HTTP ${status})`);
2187
+ case 403:
2188
+ // 禁止访问
2189
+ return new SDKError(NetworkErrorCode.UNAUTHORIZED, `无权限访问该资源 (HTTP ${status})`);
2190
+ case 404:
2191
+ // 资源不存在
2192
+ return new SDKError(NetworkErrorCode.SERVER_ERROR, `请求的资源不存在 (HTTP ${status})`);
2193
+ case 500:
2194
+ case 502:
2195
+ case 503:
2196
+ case 504:
2197
+ // 服务器错误
2198
+ return new SDKError(NetworkErrorCode.SERVER_ERROR, `服务器错误,请稍后重试 (HTTP ${status})`);
2199
+ default:
2200
+ // 其他 HTTP 错误
2201
+ return new SDKError(NetworkErrorCode.CONNECTION_FAILED, `网络请求失败: ${statusText || 'Unknown Error'} (HTTP ${status})`);
2202
+ }
2203
+ }
2204
+ /**
2205
+ * 将任意错误转换为 SDKError
2206
+ * @param error - 原始错误对象
2207
+ * @param taskId - 任务 ID(用于日志记录)
2208
+ * @returns SDKError 实例
2209
+ * @description 统一将各种类型的错误转换为 SDKError,便于上层统一处理
2210
+ * @private
2211
+ */
2212
+ convertToSDKError(error, taskId) {
2213
+ // 如果已经是 SDKError,直接返回
2214
+ if (error instanceof SDKError) {
2215
+ return error;
2216
+ }
2217
+ // 如果是普通 Error 对象
2218
+ if (error instanceof Error) {
2219
+ // 检查是否是网络相关的错误
2220
+ const errorMessage = error.message.toLowerCase();
2221
+ if (errorMessage.includes('timeout') || errorMessage.includes('timed out')) {
2222
+ return new SDKError(NetworkErrorCode.REQUEST_TIMEOUT, `请求超时 - Task: ${taskId}`, error);
2223
+ }
2224
+ if (errorMessage.includes('network') || errorMessage.includes('fetch') || errorMessage.includes('connection')) {
2225
+ return new SDKError(NetworkErrorCode.CONNECTION_FAILED, `网络连接失败 - Task: ${taskId}: ${error.message}`, error);
2226
+ }
2227
+ if (errorMessage.includes('abort') || errorMessage.includes('cancel')) {
2228
+ return new SDKError(OperationErrorCode.OPERATION_CANCELLED, `操作已取消 - Task: ${taskId}`, error);
2229
+ }
2230
+ // 默认作为操作失败处理
2231
+ return new SDKError(OperationErrorCode.OPERATION_FAILED, `播报任务执行失败 - Task: ${taskId}: ${error.message}`, error);
2232
+ }
2233
+ // 如果是字符串或其他类型
2234
+ const errorMessage = String(error);
2235
+ return new SDKError(OperationErrorCode.OPERATION_FAILED, `播报任务执行失败 - Task: ${taskId}: ${errorMessage}`);
2236
+ }
2151
2237
  }
2152
2238
 
2153
2239
  /**
@@ -2325,7 +2411,7 @@ function compareVersionCompatibility(version1, version2) {
2325
2411
  * SDK 版本号
2326
2412
  * @const {string} SDK_VERSION
2327
2413
  */
2328
- const SDK_VERSION = '2.1.1';
2414
+ const SDK_VERSION = '2.1.2';
2329
2415
 
2330
2416
  /**
2331
2417
  * @fileoverview 统一的3D数字人SDK入口类
@@ -1921,6 +1921,19 @@
1921
1921
  body: JSON.stringify(requestBody),
1922
1922
  signal: task.controller.signal,
1923
1923
  openWhenHidden: true,
1924
+ /**
1925
+ * 连接建立时的回调,用于检查 HTTP 状态码
1926
+ * @param response - HTTP 响应对象
1927
+ * @throws {SDKError} 当 HTTP 状态码异常时抛出对应的 SDKError
1928
+ */
1929
+ onopen: (response) => __awaiter(this, void 0, void 0, function* () {
1930
+ // 检查 HTTP 状态码,处理 401 token 过期等异常
1931
+ if (!response.ok) {
1932
+ const error = this.createHttpError(response.status, response.statusText, task.id);
1933
+ this.handleTaskError(task, error);
1934
+ throw error;
1935
+ }
1936
+ }),
1924
1937
  onmessage: (event) => {
1925
1938
  this.handleTaskResponse(task, event.data);
1926
1939
  },
@@ -1928,13 +1941,17 @@
1928
1941
  this.handleTaskClose(task);
1929
1942
  },
1930
1943
  onerror: (error) => {
1931
- this.handleTaskError(task, error);
1932
- throw new Error(`Task ${task.id} request failed: ${error}`);
1944
+ // 将所有异常统一转换为 SDKError
1945
+ const sdkError = this.convertToSDKError(error, task.id);
1946
+ this.handleTaskError(task, sdkError);
1947
+ throw sdkError;
1933
1948
  }
1934
1949
  });
1935
1950
  }
1936
1951
  catch (error) {
1937
- this.handleTaskError(task, error);
1952
+ // 将所有异常统一转换为 SDKError
1953
+ const sdkError = this.convertToSDKError(error, task.id);
1954
+ this.handleTaskError(task, sdkError);
1938
1955
  }
1939
1956
  });
1940
1957
  }
@@ -2022,15 +2039,19 @@
2022
2039
  * 处理任务错误
2023
2040
  * @param task - 播报任务
2024
2041
  * @param error - 错误对象
2025
- * @description 处理任务执行过程中的错误
2042
+ * @description 处理任务执行过程中的错误,防止重复触发错误回调
2026
2043
  * @private
2027
2044
  */
2028
2045
  handleTaskError(task, error) {
2029
2046
  var _a, _b;
2047
+ // 如果任务已经是失败或取消状态,不再重复处理,防止回调被多次触发
2048
+ if (task.status === BroadcastTaskStatus.FAILED || task.status === BroadcastTaskStatus.CANCELLED) {
2049
+ return;
2050
+ }
2030
2051
  task.status = BroadcastTaskStatus.FAILED;
2031
2052
  task.error = error;
2032
2053
  this.logger.error(`Task failed - ${task.id}`, error);
2033
- // 触发错误回调
2054
+ // 触发错误回调(只触发一次)
2034
2055
  (_b = (_a = this.callbacks).onError) === null || _b === void 0 ? void 0 : _b.call(_a, error);
2035
2056
  }
2036
2057
  /**
@@ -2154,6 +2175,71 @@
2154
2175
  this.queueProcessTimer = null;
2155
2176
  }
2156
2177
  }
2178
+ /**
2179
+ * 根据 HTTP 状态码创建对应的 SDKError
2180
+ * @param status - HTTP 状态码
2181
+ * @param statusText - HTTP 状态文本
2182
+ * @param taskId - 任务 ID(用于日志记录)
2183
+ * @returns SDKError 实例
2184
+ * @description 将 HTTP 错误状态码映射为对应的 SDKError
2185
+ * @private
2186
+ */
2187
+ createHttpError(status, statusText, taskId) {
2188
+ this.logger.warn(`HTTP error occurred - Task: ${taskId}, Status: ${status}`, { status, statusText });
2189
+ switch (status) {
2190
+ case 401:
2191
+ // Token 过期或未授权
2192
+ return new SDKError(exports.NetworkErrorCode.UNAUTHORIZED, `Token 已过期或无效,请重新授权 (HTTP ${status})`);
2193
+ case 403:
2194
+ // 禁止访问
2195
+ return new SDKError(exports.NetworkErrorCode.UNAUTHORIZED, `无权限访问该资源 (HTTP ${status})`);
2196
+ case 404:
2197
+ // 资源不存在
2198
+ return new SDKError(exports.NetworkErrorCode.SERVER_ERROR, `请求的资源不存在 (HTTP ${status})`);
2199
+ case 500:
2200
+ case 502:
2201
+ case 503:
2202
+ case 504:
2203
+ // 服务器错误
2204
+ return new SDKError(exports.NetworkErrorCode.SERVER_ERROR, `服务器错误,请稍后重试 (HTTP ${status})`);
2205
+ default:
2206
+ // 其他 HTTP 错误
2207
+ return new SDKError(exports.NetworkErrorCode.CONNECTION_FAILED, `网络请求失败: ${statusText || 'Unknown Error'} (HTTP ${status})`);
2208
+ }
2209
+ }
2210
+ /**
2211
+ * 将任意错误转换为 SDKError
2212
+ * @param error - 原始错误对象
2213
+ * @param taskId - 任务 ID(用于日志记录)
2214
+ * @returns SDKError 实例
2215
+ * @description 统一将各种类型的错误转换为 SDKError,便于上层统一处理
2216
+ * @private
2217
+ */
2218
+ convertToSDKError(error, taskId) {
2219
+ // 如果已经是 SDKError,直接返回
2220
+ if (error instanceof SDKError) {
2221
+ return error;
2222
+ }
2223
+ // 如果是普通 Error 对象
2224
+ if (error instanceof Error) {
2225
+ // 检查是否是网络相关的错误
2226
+ const errorMessage = error.message.toLowerCase();
2227
+ if (errorMessage.includes('timeout') || errorMessage.includes('timed out')) {
2228
+ return new SDKError(exports.NetworkErrorCode.REQUEST_TIMEOUT, `请求超时 - Task: ${taskId}`, error);
2229
+ }
2230
+ if (errorMessage.includes('network') || errorMessage.includes('fetch') || errorMessage.includes('connection')) {
2231
+ return new SDKError(exports.NetworkErrorCode.CONNECTION_FAILED, `网络连接失败 - Task: ${taskId}: ${error.message}`, error);
2232
+ }
2233
+ if (errorMessage.includes('abort') || errorMessage.includes('cancel')) {
2234
+ return new SDKError(exports.OperationErrorCode.OPERATION_CANCELLED, `操作已取消 - Task: ${taskId}`, error);
2235
+ }
2236
+ // 默认作为操作失败处理
2237
+ return new SDKError(exports.OperationErrorCode.OPERATION_FAILED, `播报任务执行失败 - Task: ${taskId}: ${error.message}`, error);
2238
+ }
2239
+ // 如果是字符串或其他类型
2240
+ const errorMessage = String(error);
2241
+ return new SDKError(exports.OperationErrorCode.OPERATION_FAILED, `播报任务执行失败 - Task: ${taskId}: ${errorMessage}`);
2242
+ }
2157
2243
  }
2158
2244
 
2159
2245
  /**
@@ -2331,7 +2417,7 @@
2331
2417
  * SDK 版本号
2332
2418
  * @const {string} SDK_VERSION
2333
2419
  */
2334
- const SDK_VERSION = '2.1.1';
2420
+ const SDK_VERSION = '2.1.2';
2335
2421
 
2336
2422
  /**
2337
2423
  * @fileoverview 统一的3D数字人SDK入口类
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@zeewain/3d-avatar-sdk",
3
3
  "type": "module",
4
- "version": "2.1.1",
4
+ "version": "2.1.2",
5
5
  "description": "SDK for ZEE Avatar WebGL integration",
6
6
  "author": "ZEEWain",
7
7
  "license": "MIT",