Software Version | 软件版本
4.6.0
Bug Description | 问题描述
背景
我尝试添加游戏 PriministAr,使用 VNDB 源。但由于网络缓慢,在加载背景图片(从 VNDB 的 10 张截图里选一张做背景大图)这一步还没有完成时我就退出了添加过程,更换网络环境,准备删除后再次添加。
但是疑似由于添加或删除过程中出现问题,导致 PriministAr 没有被真正删除。这之后直接从硬盘启动 PriministAr 后,反复出现以下致命问题。
问题描述
点击进入任何单个游戏(不限于 PriministAr)的详情界面均报错:
Cannot read properties of undefined (reading 'name')
应用重启后能重新进入主页面,但此问题仍然未解决。
日志分析
查看日志可见大量重复报错信息:
Unhandled rejection in event handler: TypeError: Cannot read properties of undefined (reading 'name')
at refreshTimerStatus (D:\ProgramData\Vnite\resources\app.asar\out\main\index.js:9556:60)
at async D:\ProgramData\Vnite\resources\app.asar\out\main\index.js:9545:5
请定位到此之前 (2026-02-06 22:44:09)的日志,见下方的 app-2026-02-06.log。
以下是我直接喂给 Copilot 做出的回答,你也可以参考一下。
根据提供的日志文件和代码分析,这个问题是由 "僵尸" 游戏监控进程 导致的。
简而言之:你(或系统)删除了一个游戏,但 vnite 的后台监控服务(Native Monitor)没有同步收到通知,仍然在监控该游戏的进程。当你运行这个已删除游戏的程序时,后台服务试图读取已不存在的数据库信息,导致程序内部报错并崩溃。
详细问题成因分析
-
游戏被删除 (22:43:12):
- 日志显示 ID 为
979067f8... 的游戏 "PriministAr" 被删除 (game:deleted)。
GameDBManager 成功从数据库中移除了该游戏的数据。
-
监控服务未同步 (Bug 核心):
- 经过代码排查,
src/main/features/monitor/services/nativeMonitor.ts 文件中缺少对 game:deleted 事件的监听。
- 这意味着,虽然数据库里删除了游戏,但底层的 C++/Native 进程监控模块并没有更新“已知游戏列表”。它仍然记录着
priministar_chs.exe 对应着 ID 979067f8...。
-
游戏进程启动 (22:44:09):
- 系统检测到
priministar_chs.exe 启动。
- Native 监控模块触发回调,告诉主程序:“ID 为
979067f8... 的游戏启动了”。
-
产生“僵尸”监控对象:
nativeMonitor 收到通知后,尝试为这个 ID 创建一个监控对象 (startPhantomMonitor)。
- 尽管数据库中已无此游戏,但代码中的容错逻辑(或默认返回值)可能允许了这个“空壳”监控对象的创建,并将其加入到了全局的
monitors 列表中。
-
致命错误 (22:44:09 及后续):
- 程序试图更新所有运行中游戏的状态 (
refreshTimerStatus)。
- 该函数遍历
monitors 列表,并尝试从数据库获取每个游戏的元数据(如名称)。
- 代码逻辑是:
name: (await GameDBManager.getGame(gameId)).metadata.name。
- 由于游戏已从数据库彻底删除,
getGame(gameId) 返回了空对象或 undefined。
- 尝试读取空对象的
.metadata 属性时,并未报错(得到 undefined),但在尝试读取 undefined.name 时,抛出了 TypeError: Cannot read properties of undefined (reading 'name')。
-
持续报错:
- 由于这个“僵尸”监控对象一旦加入
monitors 列表就没有被移除(因为报错中断了后续逻辑),之后每一次触发状态刷新(比如点击任何游戏详情、或者定时刷新),都会运行同一段代码,遍历到同一个不存在的游戏,再次抛出同样的错误,导致 App 功能瘫痪。
总结
这是一个典型的 状态不同步 (State Desynchronization) 问题。
- 根本原因:
nativeMonitor 模块没有监听 game:deleted 事件来清理底层监控列表。
- 直接原因:
refreshTimerStatus 函数在读取数据库结果时缺少空值检查(Null Check)。
修复建议 (针对开发者):
- 在
nativeMonitor.ts 中添加对 game:deleted 的监听,一旦游戏删除,立即调用 updateKnownGames() 或移除对应的监控存根。
- 在
refreshTimerStatus 中添加防御性代码,如果 getGame() 返回空,应自动将该无效的 monitor 从列表中移除,而不是让整个程序崩溃。
Error Log | 问题日志
完整日志: app.log
最相关部分:app-2026-02-06.log
Screenshots | 问题截图
- 报错画面
- 托盘右键菜单,能证明 PriministAr 没有被真正删除的直接证据
UPD: 我直接写了个 PR #489
Software Version | 软件版本
4.6.0
Bug Description | 问题描述
背景
我尝试添加游戏 PriministAr,使用 VNDB 源。但由于网络缓慢,在加载背景图片(从 VNDB 的 10 张截图里选一张做背景大图)这一步还没有完成时我就退出了添加过程,更换网络环境,准备删除后再次添加。
但是疑似由于添加或删除过程中出现问题,导致 PriministAr 没有被真正删除。这之后直接从硬盘启动 PriministAr 后,反复出现以下致命问题。
问题描述
点击进入任何单个游戏(不限于 PriministAr)的详情界面均报错:
Cannot read properties of undefined (reading 'name')
应用重启后能重新进入主页面,但此问题仍然未解决。
日志分析
查看日志可见大量重复报错信息:
Unhandled rejection in event handler: TypeError: Cannot read properties of undefined (reading 'name')
at refreshTimerStatus (D:\ProgramData\Vnite\resources\app.asar\out\main\index.js:9556:60)
at async D:\ProgramData\Vnite\resources\app.asar\out\main\index.js:9545:5
请定位到此之前 (2026-02-06 22:44:09)的日志,见下方的 app-2026-02-06.log。
以下是我直接喂给 Copilot 做出的回答,你也可以参考一下。
根据提供的日志文件和代码分析,这个问题是由 "僵尸" 游戏监控进程 导致的。
简而言之:你(或系统)删除了一个游戏,但
vnite的后台监控服务(Native Monitor)没有同步收到通知,仍然在监控该游戏的进程。当你运行这个已删除游戏的程序时,后台服务试图读取已不存在的数据库信息,导致程序内部报错并崩溃。详细问题成因分析
游戏被删除 (22:43:12):
979067f8...的游戏 "PriministAr" 被删除 (game:deleted)。GameDBManager成功从数据库中移除了该游戏的数据。监控服务未同步 (Bug 核心):
src/main/features/monitor/services/nativeMonitor.ts文件中缺少对game:deleted事件的监听。priministar_chs.exe对应着 ID979067f8...。游戏进程启动 (22:44:09):
priministar_chs.exe启动。979067f8...的游戏启动了”。产生“僵尸”监控对象:
nativeMonitor收到通知后,尝试为这个 ID 创建一个监控对象 (startPhantomMonitor)。monitors列表中。致命错误 (22:44:09 及后续):
refreshTimerStatus)。monitors列表,并尝试从数据库获取每个游戏的元数据(如名称)。name: (await GameDBManager.getGame(gameId)).metadata.name。getGame(gameId)返回了空对象或undefined。.metadata属性时,并未报错(得到undefined),但在尝试读取undefined.name时,抛出了TypeError: Cannot read properties of undefined (reading 'name')。持续报错:
monitors列表就没有被移除(因为报错中断了后续逻辑),之后每一次触发状态刷新(比如点击任何游戏详情、或者定时刷新),都会运行同一段代码,遍历到同一个不存在的游戏,再次抛出同样的错误,导致 App 功能瘫痪。总结
这是一个典型的 状态不同步 (State Desynchronization) 问题。
nativeMonitor模块没有监听game:deleted事件来清理底层监控列表。refreshTimerStatus函数在读取数据库结果时缺少空值检查(Null Check)。修复建议 (针对开发者):
nativeMonitor.ts中添加对game:deleted的监听,一旦游戏删除,立即调用updateKnownGames()或移除对应的监控存根。refreshTimerStatus中添加防御性代码,如果getGame()返回空,应自动将该无效的monitor从列表中移除,而不是让整个程序崩溃。Error Log | 问题日志
完整日志: app.log
最相关部分:app-2026-02-06.log
Screenshots | 问题截图
UPD: 我直接写了个 PR #489