fix(setup): stop a failed console write from aborting setup (#152)

setup.bat runs `chcp 65001` and shows binary progress on stderr. On some
Windows consoles - the reporter's Windows Server 2012 R2 above all - that
code page cannot render non-ASCII text and the OS fails the write with
EIO. process.stderr is an ordinary stream, so the EIO arrived as an
'error' event, and with no listener attached Node rethrew it as an
uncaught exception:

    Error: write EIO { errno: -4070, code: 'EIO', syscall: 'write' }
        at log (scripts/download-binaries.mjs:84:18)
        at ensureFfmpeg (scripts/download-binaries.mjs:451:5)

Those two frames pin it exactly: line 84 is `process.stderr.write`, and
line 451 is the first log line of the whole run that contains Chinese.
The three lines before it are pure ASCII and printed fine. Nothing was
wrong with the download it was announcing - setup killed itself inside
its own progress logging and reported the native modules as unusable.

scripts/lib/console-log.mjs now wraps both streams: it listens for
'error' so the failure can never be fatal, then degrades that stream
rather than dying - first to an ASCII rendering that keeps the English
half of each bilingual line, then silent if the stream is really gone.
The streams degrade independently, so a console that gives up costs
setup.log nothing: that stdout is a redirected file. check-native.mjs
gets the same treatment, since the console that cannot print its Chinese
is exactly the one a user needs its English from.

Also report a 404 honestly. better-sqlite3 dropped its Node 20 (ABI 115)
prebuilds in 12.10.0 and @discordjs/opus 0.10.0 has none for Node 24, so
users on those majors fall through to the source build and are told to
install Python and a C++ toolchain - when switching Node major takes two
minutes. Nothing in the output said so, and the README recommended
Node 20 as if it still worked.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
saopig1andClaude Opus 5 committed 2026-08-25 17:59:31 +08:00
1 parent af1dac848d
commit 5e9ae49f52
5 files changed
+321 -8

No files matched your search

+5 -5
View File
@@ -65,22 +65,22 @@
先装好 Node.js,其余依赖(含内置 FFmpeg)全部自动安装。
```
1. 安装 Node.js 20 LTS 或 22 LTS(https://nodejs.org/ 或 https://nodejs.cn/)
1. 安装 Node.js 22 LTS(https://nodejs.org/ 或 https://nodejs.cn/)
2. 下载或 clone 本项目
3. 双击 scripts\setup.bat (安装依赖并构建,不含 Node.js 本身)
4. 双击 scripts\start.bat (启动机器人)
5. 浏览器打开 http://localhost:3000
```
> **先装 Node.js 20 LTS 或 22 LTS**([nodejs.org](https://nodejs.org/) / 国内镜像 [nodejs.cn](https://nodejs.cn/))。`setup.bat` 检测到没装 Node 时会给出下载地址并退出,不会替你安装。
> **先装 Node.js 22 LTS**([nodejs.org](https://nodejs.org/) / 国内镜像 [nodejs.cn](https://nodejs.cn/))。`setup.bat` 检测到没装 Node 时会给出下载地址并退出,不会替你安装。
>
> 之后 `setup.bat` 会运行 `npm install` 安装所有依赖(包括内置 FFmpeg),按当前 Node 版本准备好原生模块,最后构建项目。之后每次只需双击 `start.bat` 启动。
>
> 更新的 Node 大版本(如 24)也能用,但通常没有现成的 opus / better-sqlite3 预编译包,安装脚本会改用源码编译,需要 C/C++ 构建工具且耗时更久——所以推荐 20 / 22 LTS。**装好之后不要再换 Node 大版本**:原生模块只能在编译它的那个版本上加载,换版本后必须重新运行 `setup.bat`(脚本会自动检测并重装,见下方常见问题)。
> 其他 Node 大版本也能用,但通常没有现成的预编译包,安装脚本会改用源码编译,需要 Python + C/C++ 构建工具且耗时更久:better-sqlite3 从 12.10.0 起不再提供 Node 20(ABI 115)的预编译包,@discordjs/opus 0.10.0 也没有 Node 24(ABI 137)的——所以推荐 22 LTS。**装好之后不要再换 Node 大版本**:原生模块只能在编译它的那个版本上加载,换版本后必须重新运行 `setup.bat`(脚本会自动检测并重装,见下方常见问题)。
### 方式二:手动安装(所有系统)
**前置条件:** [Node.js 20 LTS 或 22 LTS](https://nodejs.org/)(推荐;更新的大版本可用但需要源码编译原生模块)和一个 TeamSpeak 服务器(TS3/TS5/TS6 均可)。
**前置条件:** [Node.js 22 LTS](https://nodejs.org/)(推荐;Node 20 / 24 等其他大版本可用,但需要源码编译原生模块)和一个 TeamSpeak 服务器(TS3/TS5/TS6 均可)。
FFmpeg **已自动内置**,无需手动安装。
```bash
@@ -510,7 +510,7 @@ teamspeak-music-bot/
| 层级 | 技术 |
|------|------|
| **运行时** | Node.js 20 / 22 LTS, TypeScript 5 |
| **运行时** | Node.js 22 LTS(推荐), TypeScript 5 |
| **后端框架** | Express 4, WebSocket (ws) |
| **数据库** | better-sqlite3 (SQLite) |
| **音频处理** | FFmpeg (ffmpeg-static 内置), @discordjs/opus |