Make VPN toggle actions match displayed VPN state#8887
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (4)
🚧 Files skipped from review as they are similar to previous changes (2)
📝 WalkthroughWalkthroughVPN status parsing now tolerates missing JSON values, the VPN status stream and notifier handle errors explicitly, the notifier hydrates initial state from the service, the macOS switch flow awaits dialog results, and tests cover hydration and error propagation. ChangesVPN status flow
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related issues
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Pull request overview
Adjusts VPN toggle behavior so user actions align with the VPN state shown in the UI, while hardening status handling against invalid/missing core data and stream failures.
Changes:
- Fixes toggle action selection so “switch off” states (e.g. error) trigger
startVPN()instead ofstopVPN(). - Adds initial VPN connection hydration via
isVPNConnected()and improves resilience to malformed/missing status JSON. - Adds tests covering initial hydration, error-state toggling, and status-stream error handling.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| test/features/vpn/provider/vpn_notifier_test.dart | Adds unit tests for initial hydration, error-state toggling, and stream error behavior. |
| lib/features/vpn/vpn_switch.dart | Updates macOS extension dialog flow and removes BuildContext dependency from notifier toggle call. |
| lib/features/vpn/provider/vpn_status_notifier.dart | Adds stream error handling for VPN status updates. |
| lib/features/vpn/provider/vpn_notifier.dart | Hydrates initial status asynchronously and updates toggle logic to match displayed state. |
| lib/core/models/lantern_status.dart | Makes fromJson tolerant of missing/null status values. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Actionable comments posted: 3
🧹 Nitpick comments (1)
test/features/vpn/provider/vpn_notifier_test.dart (1)
118-142: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winAssert recovery after a stream error.
This test proves the first error is converted, but not that the notifier keeps processing later status events. Add a follow-up event assertion to catch regressions where the status stream stops after
addError.Suggested test extension
expect(status.hasValue, isTrue); expect(status.value?.status, VPNStatus.error); expect(status.value?.error, contains('status stream failed')); + + service.statusController.add( + LanternStatus(status: VPNStatus.connected), + ); + await _pumpProviderQueue(); + + expect(container.read(vpnProvider), VPNStatus.connected);🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@test/features/vpn/provider/vpn_notifier_test.dart` around lines 118 - 142, The vpn_notifier_test case currently verifies that a status stream error is converted to VPNStatus.error, but it does not confirm recovery afterward; extend the test around vPNStatusProvider and vpnProvider by emitting a later valid status event from _FakeLanternService after addError and asserting the notifier updates to that new status. This should be added in the existing “status stream errors become VPNStatus.error instead of crashing” test so it catches regressions where the stream stops processing after an error.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@lib/features/vpn/provider/vpn_notifier.dart`:
- Around line 23-41: The VPN notifier hydration flow can overwrite a real
stream-driven status with a stale initial result. Update VPNNotifier’s hydration
logic around _hydrateInitialStatus and the ref.listen handler so the first
status emitted from vPNStatusProvider is treated as authoritative and any later
isVPNConnected() fallback only applies if the stream has not emitted yet. Add a
guard in VPNNotifier to track whether the stream has produced a value before
assigning state from hydration, and ensure disconnected fallback does not
replace an already observed connected/disconnected status.
- Around line 101-119: Catch exceptions thrown by isVPNConnected() inside
_hydrateInitialStatus() before the result.fold handling, since unawaited callers
won’t observe them and the provider can stay stuck in the fallback state. Update
vpn_notifier.dart’s _hydrateInitialStatus method to wrap the
await/ref.read(lanternServiceProvider).isVPNConnected() call in error handling,
log the thrown failure with appLogger.error, and transition state to
VPNStatus.error when appropriate, while still preserving the existing Left/right
fold behavior for normal results.
In `@lib/features/vpn/provider/vpn_status_notifier.dart`:
- Around line 13-24: The outer try/catch around the await for in
vpn_status_notifier.dart causes the stream subscription to terminate on the
first error, so update vpnStatusNotifier/VPN status handling to keep listening
after recoverable failures. Handle errors inside the statusStream consumption
path or re-establish the subscription after logging in appLogger.error, and keep
yielding LanternStatus error states without exiting the notifier loop.
---
Nitpick comments:
In `@test/features/vpn/provider/vpn_notifier_test.dart`:
- Around line 118-142: The vpn_notifier_test case currently verifies that a
status stream error is converted to VPNStatus.error, but it does not confirm
recovery afterward; extend the test around vPNStatusProvider and vpnProvider by
emitting a later valid status event from _FakeLanternService after addError and
asserting the notifier updates to that new status. This should be added in the
existing “status stream errors become VPNStatus.error instead of crashing” test
so it catches regressions where the stream stops processing after an error.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: a9466ca5-415d-494d-aa2d-19acaa713859
📒 Files selected for processing (5)
lib/core/models/lantern_status.dartlib/features/vpn/provider/vpn_notifier.dartlib/features/vpn/provider/vpn_status_notifier.dartlib/features/vpn/vpn_switch.darttest/features/vpn/provider/vpn_notifier_test.dart
Resolves https://github.com/getlantern/engineering/issues/3636
Fixes a VPN toggle mismatch where the UI could show the VPN as off or errored, but tapping the toggle would try to disconnect instead of reconnect.
Summary by CodeRabbit
Summary by CodeRabbit
New Features
Bug Fixes