做产品久了会发现,「坏」是分等级的。
大多数故障用户能自己消化:这次没识别对,再说一遍;网络卡了,等一会儿。烦,但不致命——因为他手里还有牌。
真正会让人卸载的是另一种:怎么点都失败,而且完全不知道该做什么。这一版就是专门去找这种死路。
起因不是用户报的,是我们自己去翻的
这一版没有对应的用户投诉。是 James 说了一句:「把所有可能出现失败的地方全列出来,再把机制定下来。」
于是我们把整条链路拆开,一段一段问「这里失败会怎样」:录音、落盘、数据库、云端识别、文字插入、上传、服务端、发布。列出 35 个失败点,逐个写下现有机制。大部分已经有兜底——但有三个是真空的。
第一个:一次 401,永久卡死
Xtype 每台安装有一个凭证,云端识别靠它认人。如果服务端不再认这个凭证(比如记录被清、凭证轮换),会返回 401。
问题在于我们当初把 401 和「额度用完」归成了同一类:都不重试、都不回退。额度用完确实重试无用——但 401 不一样,重新登记一次就好了。
后果是:一旦发生,之后每一次听写都失败,重启没用、重装可能也没用,用户没有任何自救手段。这就是标准的死路。
现在 401 单独成一类:自动重新登记,然后用刚才那段录音重试。大多数情况下你根本不会察觉。
第二个:以为提了需求,其实没发出去
App 里的「AI 提需求」,说一段话就能提。但如果那一刻网络不通,我们只是在本地记了个错误——没有任何人再管它。
用户这边看到的是:我说完了,点了提交,然后……就没有然后了。他以为提上去了。
这种失败比明确报错更糟,因为它偷走的是信任。现在:投递失败会明说「已存在本机」,下次打开自动重投,列表里也能手动点「重发」。
第三个:讲完才发现磁盘满了
录音每分钟往盘上写一次。写失败原本只打一行日志。
想象一下:你讲了八分钟,讲完,然后被告知存不下。前面那七分钟你本来是有机会补救的——只要早点告诉你。
现在一发现写不进盘就立刻提醒,一次听写只提醒一次,不啰嗦。
一个我们自己造的坑
审计做完之后,James 截了张图问:怎么有两个 Xtype 在跑?
查下来是真的:/Applications 一个,我们编译验证时留在仓库里的构建产物一个。macOS 只按路径去重,同一个程序放在两个位置,它就当成两个 app,各起一个进程——两套热键监听、两套录音、两套写同一个数据库。
这个坑是我们自己开发时造的,但用户也可能遇到(比如从两个位置各装了一份)。现在启动时会检查:同一个程序已经在跑,后打开的那个自动退出,并把已经在运行的唤到前面。
剩下没修的,也写下来
审计里还有四个缺口没修,写在文档里没藏着:麦克风异常的提示太笼统;服务端记账失败时会丢掉已经转写好的文字(钱花了,结果没给用户);重新转写长录音中途失败要从头再来;免费额度的本地计数会滞后于服务端。
写下来的意义是:下次谁碰这块代码,知道这里有个已知的洞,而不是以为它已经完备。