Suppress "Current WiFi is not allowed" notification for scheduled backups#2444
Conversation
m3nu
left a comment
There was a problem hiding this comment.
Thanks for tackling this — the issue is real and the intent is correct. A few concerns before this can be merged:
1. Fragile string comparison (blocking)
if msg['message'] != 'Current Wifi is not allowed.':This compares against a raw English string literal. If the message in create.py:124 is ever reworded, this check silently breaks with no test or compiler to catch it.
Suggested approach: Have BorgCreateJob.prepare() return a structured level field for expected skips:
# In create.py, for WiFi and metered checks:
ret['message'] = trans_late('messages', 'Current Wifi is not allowed.')
ret['level'] = 'info' # Expected skip, not an error
return retThen in scheduler.py:
else:
level = msg.get('level', 'error')
if level == 'error':
logger.error('Conditions for backup not met. Aborting.')
logger.error(msg['message'])
notifier.deliver(
self.tr('Vorta Backup'),
translate('messages', msg['message']),
level='error',
)
else:
logger.info('Backup skipped: %s', msg['message'])
self.pause(profile_id)This avoids string matching entirely and is extensible to other expected-skip cases.
2. Metered connection has the same problem
'Not running backup over metered connection.' (create.py:132) is the same class of issue — a user-configured skip reported as an error notification. The structured level approach handles both naturally. Would be good to fix both while we're here.
3. Unrelated change in archive_tab.py
Removing self.selected_archives = None is fine cleanup but should be a separate PR to keep the fix focused.
|
Thank you for the detailed review @m3nu. I have implemented your
Please review the updated implementation. |
|
Hi @m3nu, all CI checks are now passing and the conflict is resolved. The PR is ready for your re-review whenever you have time. |
|
Hi @m3nu, all requested changes have been implemented — structured level field added in create.py for both WiFi and metered connection cases, scheduler.py updated to use msg.get('level', 'error'), and the unrelated archive_tab.py change removed. All 5 CI checks are passing. Could you re-review when you have a moment? Happy to make any further adjustments. |
m3nu
left a comment
There was a problem hiding this comment.
Review
The approach is sound and correctly addresses #2231. The structured level field avoids fragile string matching and handles both WiFi and metered connection cases cleanly.
Before merging, two things to address:
-
Squash the stale commit. The first commit "Remove unused self.selected_archives variable in ArchiveTab" was reverted in a later commit — please squash or rebase to remove it from history.
-
Add a unit test. There's no test covering the new branching logic. At minimum, a test should verify:
BorgCreateJob.prepare()returnslevel='info'when WiFi is disallowedBorgCreateJob.prepare()returnslevel='info'for metered connectionsscheduler.create_backup()does not callnotifier.deliver()withlevel='error'when the prepare result haslevel='info'
Without a test, someone could remove the
levelfield fromcreate.pyand the regression would go undetected.
Minor note: msg.get('level', 'error') defaults to 'error' for all other prepare() failure paths that don't set level — this is the correct behavior, just worth being explicit about in a comment.
14c7078 to
f765ef4
Compare
|
Hi @m3nu, all three items addressed — unit tests added for WiFi and metered connection cases, comment added explaining the msg.get('level', 'error') default behavior, and stale commit squashed into one clean commit. All 5 CI checks passing. Ready for re-review when you have a moment. |
|
Hi @m3nu, just checking in — all three items from your review are addressed: unit tests added, comment added for msg.get('level', 'error') default behavior, and stale commit squashed. All 5 CI checks passing. Let me know if anything else is needed before merge. |
m3nu
left a comment
There was a problem hiding this comment.
Thanks for the updates — the core approach is correct and this is close to merge-ready. A few things to clean up:
1. Commit history
The PR still contains the stale commit 07ce18c ("Remove unused self.selected_archives variable in ArchiveTab") that was reverted in the subsequent commit. To clean this up:
git rebase -i origin/masterThen mark the first commit as drop (or squash everything into a single commit). This keeps the merge history clean and avoids confusing future readers of git log. We typically squash-merge anyway, but it's good practice to keep your branch tidy before requesting review — it signals that what reviewers see is the final, intentional state.
2. Missing comment on the default value
In the second review I asked for a brief comment explaining why msg.get('level', 'error') defaults to 'error'. The reason this matters: a future contributor adding a new failure path in prepare() might not realize they need to set level — the default silently does the right thing, but only if someone understands the convention. A one-line comment makes that explicit:
# Default to 'error' — prepare() paths that set level='info' are intentional
# skips (WiFi disallowed, metered connection) that don't warrant a notification.
level = msg.get('level', 'error')3. Strengthen the scheduler test assertion
The current assertion:
for call in mock_notifier.deliver.call_args_list:
assert call.kwargs.get('level') != 'error'This has a subtle problem: if deliver is never called (e.g., an exception is raised before reaching it, or the mock is set up wrong), the loop body executes zero times and the test passes — it tells you nothing went wrong when something clearly did. This is called a vacuous truth in testing and it's a common pitfall with loop-based assertions.
A stronger version:
# The "Starting backup" notification should still fire (level='info'),
# but no error notification should be sent for an expected skip.
assert mock_notifier.deliver.call_count == 1
assert mock_notifier.deliver.call_args.kwargs.get('level') != 'error'This fails if deliver is never called, and also verifies that exactly one notification (the "Starting backup" one) was sent — confirming the error notification was actually suppressed rather than just being absent for some other reason.
218c5a0 to
8f93793
Compare
|
Hi @m3nu, fixed the lint issue — shortened the comment above msg.get('level', 'error') to fit within the line limit. All 5 CI checks passing including lint. Ready for re-review when you have a moment. |
Use structured level field in create.py for WiFi and metered connection skips instead of fragile string comparison. Add unit tests covering both skip cases and notification suppression. Fixes borgbase#2231
8f93793 to
abdec20
Compare
|
Hi @m3nu, all three items addressed:
All 5 CI checks passing. Ready for final re-review. |
Description
Suppresses the error notification when a scheduled backup is skipped
because the current WiFi network is not allowed. This is intentional
behavior, not an error, so users should not receive an error
notification in this case.
Related Issue
Fixes #2231
Motivation and Context
When a user marks a WiFi network as disallowed, Vorta correctly skips
the backup. However, it was still sending an error notification saying
"Current WiFi is not allowed" — which is confusing since this is
expected behavior, not a failure.
The fix adds a check in the create_backup() method in scheduler.py
to suppress the notification when the message indicates WiFi is not
allowed.
How Has This Been Tested?
Code review confirms the notification delivery is now conditional on
the message not being WiFi-related. No functional change to backup
behavior — only the notification is suppressed.
Types of changes
Checklist: