Skip to content

错误处理

SDK 抛出的每一种失败都是 TtsError,携带机器可读的 code。宽泛捕获,然后按 code 分支处理。

ts
import { TtsError, isTtsError } from "@optimalai/react-native";

try {
  await tts.synthesizeToFile({ text: "你好。" });
} catch (error) {
  if (isTtsError(error)) {
    console.warn(error.code, error.message, error.details);
  } else {
    throw error;
  }
}

优先用 isTtsError 而不是 instanceof —— 当 bundle 里存在重复的模块实例时, 前者依然可靠。

错误码一览

Code含义可恢复?
MODEL_NOT_FOUND某个模型资产无法解析。致命 —— 需要 reset()
MODEL_CORRUPT资产存在但校验失败。致命 —— 需要 reset()
UNSUPPORTED_DEVICE设备或系统低于基线。致命 —— 需要 reset()
BUSY已有加载或合成在进行中。可以 —— 等当前任务结束后重试。
INVALID_TEXT文本含词典外单词或不支持的字符。可以 —— 修改文本。
TEXT_TOO_LONG输入超过 2000 个 code point。可以 —— 切分文本。
TEXT_SEGMENT_TOO_LONG某段无法切到 300 个 code point 以下。可以 —— 切分文本。
INFERENCE_FAILEDONNX session 在生成音频时失败。通常可以 —— 重试;反复出现则 reset()
OUTPUT_EXISTSoutputPath 已指向一个文件。可以 —— 删除该文件或换路径。
OUTPUT_WRITE_FAILEDWAV 无法写入磁盘。可以 —— 检查权限与剩余空间。

致命错误码需要 reset

MODEL_NOT_FOUNDMODEL_CORRUPTUNSUPPORTED_DEVICE 会把 client 置为 failed。从 failed 状态不能直接调用 load(),必须先 reset()

ts
if (tts.status() === "failed") {
  await tts.reset();
}
await tts.load();

同一时刻只能有一次合成

一个 client 同时只跑一次合成。在前一次进行中再发起,会抛 BUSY

ts
// 这里会抛 BUSY。
await Promise.all([
  tts.synthesizeToFile({ text: "第一句。" }),
  tts.synthesizeToFile({ text: "第二句。" }),
]);

应该串行化:

ts
for (const text of ["第一句。", "第二句。"]) {
  await tts.synthesizeToFile({ text });
}

load() 同理:当 client 处于 loadingsynthesizing 时调用它会抛 BUSY。 如果确实需要并行,请创建第二个 client —— 但要注意每个 client 都会打开自己的 ONNX session 并占用各自的内存。

词典外文本

不在内置词典中的英文单词会以 INVALID_TEXT 失败。Beta 版没有 eSpeak 回退 —— 这是刻意的,目的是把 GPL 代码挡在依赖图之外。

中文字符若不在中文词典中,同样会失败。

ts
try {
  await tts.synthesizeToFile({ text: "Supercalifragilistic" });
} catch (error) {
  if (isTtsError(error) && error.code === "INVALID_TEXT") {
    // 给用户提示"这个词暂不支持"。
  }
}

请在合成之前校验或清洗用户输入,而不是任由一个生僻词打断整批任务。

在 UI 中呈现错误

一个小助手函数既能保留 code,又不会泄露堆栈:

ts
function errorMessage(error: unknown): string {
  if (isTtsError(error)) return `${error.code}: ${error.message}`;
  return error instanceof Error ? error.message : "Unknown error";
}

TtsError 还带有一个可选的 details 记录,用于补充诊断上下文 —— 请记录它,但 不要展示给用户。