故障排查
先收集三样信息:完整报错与退出码、执行的命令与构建渠道、Node/npm/Rust/Cargo 版本及测试环境变量。顶栏「日志」能查看装载结果、拒绝原因与最近 300 条观测;终端与浏览器开发者工具用于看构建和运行时异常。报告问题时不要附带私钥、访问凭证或与本机身份相关的路径。
症状速查
| 症状 | 常见原因 | 处理 |
|---|---|---|
npm run dev 立即退出,提示端口被占用 | 5173 或 5174 已有进程 | 结束占用进程;不要只改一个端口 |
npm install 失败、依赖树异常 | Node 版本不符、混用包管理器、registry 或代理 | 切到 Node 24.x,按锁文件重装 |
构建时报 acgcore 编译失败 | 缺 wasm32-unknown-unknown 或离线缓存 | 安装目标;必要时先联网取依赖 |
| 测试找不到系统 Edge | 环境没有 Edge | 设 ADV_TEST_BROWSER 并安装 Playwright 浏览器 |
| 浏览器测试连不上本地服务 | WSL 镜像网络、代理变量 | 设 ADV_TEST_HOST=127.0.0.2,移除代理变量 |
test:tauri 报找不到外壳 | 宿主未启动或 9437 未开放 | 先启动调试版宿主,再连 CDP |
| 启动即显示「已拒绝启动」 | 渠道、RPM 或入口哈希不一致 | 重新构建匹配渠道的产物 |
| 装载被拒绝 | 清单、签名、policy 或版本不满足 | 按原因码逐项检查 |
| 信任页空白或一直等待 | 5174 未启动、iframe 被拦、字体未加载 | 检查两个开发服务器与信任页源 |
| 设置里没有「界面实现」选项 | 当前每个界面只有一个候选,且无已卸载选择 | 正常状态;装载其他实现后再检查 |
| 换皮后部分外观未变化 | 字段被拒绝、图片缺失、名称未匹配或浏览器不支持选择器 | 查看日志,核对皮肤目录、控件名与字段范围 |
| 皮肤回到内置样式 | 主动选择不换皮、所属单元卸载或皮肤读取失败 | 在画面组查看选择与来源;检查日志和包是否装载 |
| 发布扫描命中调试标记 | 产物含 debug 渠道或扫描了源码目录 | 用 release 重新构建,只扫目标产物 |
端口占用
开发服务器占用两个固定端口:5173 为外壳,5174 为独立源信任页;文档站使用 5175。build/dev.mjs 对 5173/5174 设置 strictPort,被占用时直接失败,不会自动换端口——信任页的源参与独立源关系,端口漂移会让外壳连不上它。
在 Windows PowerShell 中查占用:
Get-NetTCPConnection -LocalPort 5173 -State Listen |
Select-Object LocalPort, OwningProcess
Get-Process -Id <占用进程的 PID>确认是旧开发服务器后,结束进程再重试:
Stop-Process -Id <PID>不要用「把 5173 改成 5176」的方式绕过。只改一个端口会同时破坏 Vite 配置、信任页源与测试假设;要改就必须同步修改所有引用点并重新验证。文档站固定 5175,见下文。
依赖安装失败
先确认 node --version 为 24.x,且只使用 npm。常见原因:
| 原因 | 处理 |
|---|---|
| Node 不是 24.x | 切换版本,删除 node_modules/ 后用锁文件重装 |
| 混用 pnpm/yarn | 只用 npm;不要保留其他包管理器的锁文件 |
| 依赖树被手动升级破坏 | npm ci 按 package-lock.json 重建 |
| registry 不可达或证书错误 | 检查 registry 与网络;不要回显含凭证的代理地址 |
| 代理拦截回环地址 | 跑本地测试前移除 http_proxy/https_proxy |
npm cinpm ci 会删除并重建 node_modules/,需要锁文件存在;它不会替你解决 Node 版本或 registry 问题。
wasm32 目标缺失
典型报错来自 build/acgcore-plugin.ts,提示需要 wasm32-unknown-unknown。这不是前端依赖缺失,重装 node_modules/ 无效。
rustup target add wasm32-unknown-unknown
rustup target list --installed输出中应包含 wasm32-unknown-unknown。再单独验证 acgcore:
cargo build --offline --release --target wasm32-unknown-unknown --manifest-path acgcore/Cargo.toml若离线构建报缺少 crate,说明本机 Cargo 缓存不完整。先在可联网环境获取依赖,再回到离线构建:
cargo fetch --manifest-path acgcore/Cargo.toml不要删除 Cargo.lock 来「重新求解」;锁文件是离线构建可复现的前提。
测试浏览器
页面实测与兼容性测试使用 Playwright,并分别确认工具连接和测试结果。下列设置只影响仓库既有回归脚本,不代表文档站页面测试结果。
npm test 的浏览器项目默认使用系统 Edge(channel: 'msedge')。没有 Edge 时,测试会在启动浏览器阶段失败,而不是在用例里失败。
| 环境变量 | 取值 | 说明 |
|---|---|---|
ADV_TEST_BROWSER | webkit、chromium、firefox | 改用 Playwright 自带浏览器 |
ADV_TEST_HOST | localhost 或回环地址 | 把 web 测试服务绑到该地址 |
ADV_TEST_PORT | 1–65535 的整数 | 覆盖 web 测试项目的独立监听端口;默认端口被系统策略拒绝或占用时使用 |
PowerShell 示例:
$env:ADV_TEST_BROWSER = 'chromium'
npm run test:web首次使用 Playwright 浏览器时先安装对应引擎,例如 npx playwright install chromium。
WSL 镜像网络下,进程可能连不上自己的 127.0.0.1;改用 127.0.0.2,并移除代理变量:
$env:ADV_TEST_BROWSER = 'chromium'
$env:ADV_TEST_HOST = '127.0.0.2'
Remove-Item Env:http_proxy -ErrorAction SilentlyContinue
Remove-Item Env:https_proxy -ErrorAction SilentlyContinue
npm run test:webADV_TEST_BROWSER 只接受上述三个值;ADV_TEST_HOST 只接受 localhost 或回环地址,填公网地址会被拒绝。代理变量会让浏览器连不上本地测试服务。
WebView2 远程调试
真实宿主测试连接已经运行的宿主,而不是启动新浏览器:
npm run build:debug构建调试版前端;- 以
debug-channel特性启动 Windows 宿主; - 确认宿主自动开放的 WebView2 远程调试端口 9437 可连接;
- 再运行
npm run test:tauri。
仓库脚本固定连接:
http://127.0.0.1:9437test/host/native-runner.js 在已有上下文中查找地址以 http://tauri.localhost 或 tauri://localhost 开头的页面;找不到时报「未找到待测试的 Tauri 外壳;每次运行须从正常启动的应用开始」。不要先让脚本冷启动应用,也不要在应用尚未进入「框架就绪」时运行。
检查端口:Test-NetConnection -ComputerName 127.0.0.1 -Port 9437。
Windows 宿主在 debug-channel 条件下已传入 --remote-debugging-port=9437,仓库脚本只连接;发布渠道不带此参数。端口未开放时先核对启动的是否为本次调试构建,不要只检查前端渠道。不要把 9437 暴露到非回环地址;它等同于把页面调试能力开放给网络。
首次运行被拒绝
启动失败时界面停在「已拒绝启动」,显示原因码,并且不加载任何根插件。常见原因:
| 原因码 | 可能原因 | 处理 |
|---|---|---|
GUARD_RPM_HASH_MISMATCH | 前端渠道与产物常量不符;rpm.json 不一致 | 用对应渠道重新构建;不要混用旧 dist/ |
GUARD_ROOT_ENTRY_MISMATCH | 根插件入口字节与 RPM 记录不符 | 清理产物后重新构建;检查是否改过生成文件 |
GUARD_INDETERMINATE | rpm.json 形状不合格、读取失败或拿不到宿主后端 | 检查构建完整性;查看终端与日志 |
GUARD_SIGNATURE_INVALID | 签名清单或单元签名无效 | 检查签名文件、公钥与清单来源 |
排查顺序:确认执行的是匹配渠道的构建;清理 dist/ 后重建;确认 rpm.json 由本次构建生成;Tauri 端确认握手未因渠道或哈希不一致而中断。仍失败时保留原因码与日志,按反馈渠道报告。原因码全集见装载原因码。
Cargo 离线构建失败
acgcore 的测试与构建使用 --offline:
cargo test --manifest-path acgcore/Cargo.toml --offline
cargo build --offline --release --target wasm32-unknown-unknown --manifest-path acgcore/Cargo.toml离线失败通常说明缓存不完整或锁文件与缓存不匹配:确认 Cargo.lock 未被修改;在可联网环境执行 cargo fetch 取得依赖;再回到离线命令验证。若代理拦截 crates.io,先解决网络,不要把依赖手工复制进仓库。
宿主测试不属于离线命令,但仍受 Cargo 缓存与平台依赖影响:
cargo test --manifest-path src-tauri/Cargo.toml --features debug-channel缺少系统库(例如 Linux 的 WebKitGTK 开发包)会以链接错误出现,不是 Rust 代码错误;按环境与依赖补齐平台前置。
发布扫描误报
扫描器只查两个标记:前端开发挂载标记 __ADV_DEV_ONLY_MOUNT__ 与 Rust 调试路由标记 ADV-DEBUG-ROUTE-MARKER。正确用法是只扫描目标产物:
npm run build:release
npm run scan:release -- dist/宿主二进制构建完成后,再把实际二进制路径传给同一命令。常见误报与处理:
| 误报来源 | 处理 |
|---|---|
扫描了源码目录或 node_modules/ | 只扫 dist/ 与最终二进制 |
| 扫描了 debug 产物 | 用 build:release 重新构建后再扫 |
dist/ 中残留旧文件 | 清理输出目录后重新构建 |
| 调试代码被错误 import 进 release 入口 | 修代码依赖,不要加排除规则 |
命中时命令返回 1,并把文件与标记打印到标准错误。发布检查失败就应阻止发布;给扫描器加排除项只会掩盖问题。
文档站端口 5175
文档站是独立工程,位于 docs-site/,不是框架开发服务器的一部分:
cd docs-site
npm install
npm run docs:dev配置中的开发端口是 5175,用于避开框架的 5173 与 5174。若被占用,先释放端口;不要改到 5173/5174,否则会与外壳或信任页冲突。构建与预览:
npm run docs:build
npm run docs:preview产物在 .vitepress/dist/。仓库流水线只构建文档,尚未绑定发布域名;域名与发布由部署方另行配置。
信任页与音频
信任页空白或一直等待时,按顺序检查:终端是否同时出现 5173 与 5174;是否单独打开了信任页(没有外壳连接时它不进入应用);浏览器控制台是否报告 iframe 被 CSP 拦截;内置字体是否加载失败(失败会锁定写操作);可见区域是否小于宽 300、高 200,或页面处于后台。信任页 10 秒内没有应答时,外壳报「信任页没有应答」。
音频没有声音时,先点击播放界面的「点击解锁音频」,或进行任意一次点击/按键;再检查独立设置或播放设置抽屉中的总音量与对应通道,确认当前内容确实带音频资源。内置示例「一封晚到的信」不含音频,不能用来验证音频通道。
导航、设置与皮肤
| 现象 | 核对与处理 |
|---|---|
| 主页没有章节 | 核对已装载数据包是否登记章节;空状态不预置玩法入口 |
| 章节显示「尚未开放」 | 这是当前章节可用性结果;主页不推测具体解锁条件 |
| 界面提示未能打开 | 查看日志中的参数或渲染错误;外壳会提示并尝试退回上一层,不能靠继续点按钮绕过 |
| 进入设置后运行信息与单元列表消失 | 独立设置暂时隐藏外壳这些区域,返回主页即恢复 |
| 已选实现或皮肤标「已卸载」 | 选择仍保留,暂按默认界面或内置样式显示;重装对应单元后恢复 |
| 切深色后某些颜色未换 | 核对皮肤是否只提供 light;未提供的主题保留内置颜色 |
| 皮肤布局与舞台缩放不同 | 皮肤位置与尺寸直接使用 CSS 像素,外壳显示比例另计算;不使用舞台的等比缩放 |
| 小按钮看起来没有变大 | 44×44 CSS px 下限由透明可点区域补足,视觉尺寸与排版不因此增大 |
皮肤 JSON 读取失败会整套回到内置样式;非法属性逐项拒绝;单张图片失败只跳过相应外观项。先查看顶栏「日志」,再按 Platform 皮肤约束核对,不要直接往 JSON 加任意 CSS。
画面组恢复默认会清除皮肤偏好并重新套用默认皮肤,同时恢复浅色主题、100% 缩放与默认界面实现。若想保留无皮肤外观,请显式选择「内置样式(不换皮)」。Android 返回键已能转交正在显示的信任页,只会拒绝裁决或关闭管理页,不会批准,也不会让底下的界面退栈。
Android 清单已处理系统字体大小与显示密度变化,避免这两类配置变化重建 Activity;已有模拟器验证记录。其他原因仍可能重建 Activity,例如启用开发者选项「不保留活动」:同一进程内的新 WebView 尚不能恢复原生桥、返回键与请求池,可能报告「宿主繁忙」,需要重启应用。报告时注明系统设置变化与是否发生重建;配置变化的记录不能替代 Activity 重建恢复验证。
收集信息再报告
报告问题前附上:执行的命令、退出码与完整报错;构建渠道及前端/宿主是否匹配;node --version、npm --version、rustc --version、cargo --version;是否设置了 ADV_TEST_BROWSER、ADV_TEST_HOST 或代理变量(只写变量名);顶栏日志中的原因码与相关单元 ID。