fix(client): 自动连接回调 NoSuchMethod(valueOrNull on dynamic)— 真正根因

日志显示每次节点加载,_maybeAutoConnect 回调抛 NoSuchMethodError:AsyncData 没有 valueOrNull
(在判 autoConnect 之前就崩)→ 自动连接从未生效。根因:sub 声明成裸 ProviderSubscription
(=<dynamic>),逼 listenManual 推断成 dynamic,next 变 dynamic;valueOrNull 是扩展 getter,
dynamic 上不解析 → 运行期 NoSuchMethod。修:sub 标全泛型 ProviderSubscription<AsyncValue<List<Node>>>。
(1.0.18 的竞态修复是误判,真凶是这个崩溃。)诊断日志暂留,确认后清。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
wangjia
2026-06-29 18:46:57 +08:00
parent f734126eb6
commit 7fdadace4e
3 changed files with 7 additions and 4 deletions
+5 -2
View File
@@ -9,6 +9,7 @@ import 'package:window_manager/window_manager.dart';
import 'bridge/log.dart';
import 'bridge/vpn_bridge_provider.dart';
import 'models/node.dart';
import 'pangolin_theme.dart';
import 'services/token_store.dart';
import 'shell/home_shell.dart';
@@ -128,9 +129,11 @@ class _RootFlowState extends ConsumerState<RootFlow> {
// 注意:不在此处早读 settingsProvider.autoConnect —— 其 _load 是异步(SharedPreferences),
// 启动这一刻多半还没加载完,会读到默认 false 而永久跳过。改到「节点就绪」回调里再判:
// 节点要走网络拉取,远慢于本地设置读取,那时 autoConnect 必已加载到位。
late final ProviderSubscription sub;
// 必须标全泛型:裸 ProviderSubscription(=<dynamic>)会让 listenManual 推断成 dynamic,
// next 变 dynamic → valueOrNull(扩展 getter)在 dynamic 上不解析 → 运行期 NoSuchMethod。
late final ProviderSubscription<AsyncValue<List<Node>>> sub;
sub = ref.listenManual(nodesProvider, (prev, next) {
final nodes = next.valueOrNull ?? const [];
final nodes = next.valueOrNull ?? const <Node>[];
final ready = nodes.any((n) => n.uuid.isNotEmpty);
logLine('AutoConnect', 'nodes update: total=${nodes.length} ready=$ready loading=${next.isLoading} err=${next.hasError}');
if (!ready) return;
+1 -1
View File
@@ -1,7 +1,7 @@
name: pangolin_vpn
description: 穿山甲 · Pangolin — 极简、稳定、跨平台网络加速客户端。
publish_to: "none"
version: 1.0.19+20
version: 1.0.20+21
environment:
sdk: ^3.5.0
+1 -1
View File
@@ -3,7 +3,7 @@
; 前置: 先在 client/ 跑 `flutter build windows`(Release),产物在
; ..\..\build\windows\x64\runner\Release
#define MyAppName "穿山甲 Pangolin"
#define MyAppVersion "1.0.19"
#define MyAppVersion "1.0.20"
#define MyAppPublisher "Pangolin"
#define MyAppExeName "pangolin_vpn.exe"
#define BuildDir "..\..\build\windows\x64\runner\Release"