[PR #6997] [client] Return watcher errors from network monitor instead of reporting a network change #27734

Open
opened 2026-08-05 07:09:09 -04:00 by saavagebueno · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/netbirdio/netbird/pull/6997
Author: @Optic00
Created: 7/30/2026
Status: 🔄 Open

Base: mainHead: codex/fix-network-monitor-watch-errors


📝 Commits (4)

  • 41a4627 fix network monitor watcher error handling
  • 5a56504 stabilize network monitor tests
  • 0f1b060 preserve unexpected watcher cancellation errors
  • 890af24 test: restore network monitor check overrides

📊 Changes

2 files changed (+155 additions, -13 deletions)

View changed files

📝 client/internal/networkmonitor/monitor.go (+21 -6)
📝 client/internal/networkmonitor/monitor_test.go (+134 -7)

📄 Description

Describe your changes

The network monitor's watcher goroutine (checkChanges) closed the shared event channel when the platform watcher returned an error. A closed channel made the <-event case in Listen fire in a busy loop until the debounce timer expired, so Listen returned nil — a watcher failure was reported as a network change, triggering an unnecessary client restart.

Changes:

  • checkChanges no longer closes the event channel. It reports its error on a dedicated buffered watchErrors channel, guarded by ctx.Done() so the goroutine cannot block, and exits.
  • Listen returns the watcher error wrapped (watch network changes: %w) instead of nil. On real cancellation it still returns ctx.Err(), preserving the existing clean-shutdown handling in the engine.
  • If a watcher returns context.Canceled while the listener context is still active, Listen now returns the wrapped error instead of nil, so it cannot be mistaken for a detected network change.
  • The default next-hop lookup is injectable, so the lifecycle tests no longer depend on host routes and run in restricted environments.
  • New tests cover that the event channel is not closed, the error is delivered exactly once, Listen returns the wrapped watcher error, and the unexpected-cancellation edge case.

Verification: the new edge-case test fails against the previous implementation (Listen() error = <nil>) and passes with this change. The full package suite passes with go test -race -count=1 ./client/internal/networkmonitor, without requiring host routing access.

N/A

Stack

Standalone PR based on main.

Checklist

  • Is it a bug fix
  • Is a typo/documentation fix
  • Is a feature enhancement
  • It is a refactor
  • Created tests that fail without the change (if possible)
  • This change does not modify the public API, gRPC protocols, functionality behavior, CLI / service flags, or introduce a new feature — OR I have discussed it with the NetBird team beforehand (link the issue / Slack thread in the description). See CONTRIBUTING.md.

By submitting this pull request, you confirm that you have read and agree to the terms of the Contributor License Agreement.

Documentation

Select exactly one:

  • I added/updated documentation for this change
  • Documentation is not needed for this change (internal bug fix in the client's network monitor; no user-facing behavior, API, or configuration changes)

Docs PR URL (required if "docs added" is checked)

N/A

Summary by CodeRabbit

  • Bug Fixes

    • Improved network monitoring error handling so watcher errors are reported reliably.
    • Preserved correct cancellation behavior when network watchers stop independently.
    • Prevented event channels from closing unexpectedly during monitoring.
  • Tests

    • Added coverage for watcher errors, cancellation scenarios, and event-channel behavior.
    • Improved test synchronization for more reliable results.

🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/netbirdio/netbird/pull/6997 **Author:** [@Optic00](https://github.com/Optic00) **Created:** 7/30/2026 **Status:** 🔄 Open **Base:** `main` ← **Head:** `codex/fix-network-monitor-watch-errors` --- ### 📝 Commits (4) - [`41a4627`](https://github.com/netbirdio/netbird/commit/41a4627ade99ccf7f45cd430a9238d65d42acc93) fix network monitor watcher error handling - [`5a56504`](https://github.com/netbirdio/netbird/commit/5a56504c8f9f598577907b630dababe714dad956) stabilize network monitor tests - [`0f1b060`](https://github.com/netbirdio/netbird/commit/0f1b060a7fae7f26090638fb24b00b3ca17917c0) preserve unexpected watcher cancellation errors - [`890af24`](https://github.com/netbirdio/netbird/commit/890af24a823066478c13301ca0dc88c706d2cb66) test: restore network monitor check overrides ### 📊 Changes **2 files changed** (+155 additions, -13 deletions) <details> <summary>View changed files</summary> 📝 `client/internal/networkmonitor/monitor.go` (+21 -6) 📝 `client/internal/networkmonitor/monitor_test.go` (+134 -7) </details> ### 📄 Description ## Describe your changes The network monitor's watcher goroutine (`checkChanges`) closed the shared `event` channel when the platform watcher returned an error. A closed channel made the `<-event` case in `Listen` fire in a busy loop until the debounce timer expired, so `Listen` returned `nil` — a watcher **failure** was reported as a **network change**, triggering an unnecessary client restart. Changes: - `checkChanges` no longer closes the `event` channel. It reports its error on a dedicated buffered `watchErrors` channel, guarded by `ctx.Done()` so the goroutine cannot block, and exits. - `Listen` returns the watcher error wrapped (`watch network changes: %w`) instead of `nil`. On real cancellation it still returns `ctx.Err()`, preserving the existing clean-shutdown handling in the engine. - If a watcher returns `context.Canceled` while the listener context is still active, `Listen` now returns the wrapped error instead of `nil`, so it cannot be mistaken for a detected network change. - The default next-hop lookup is injectable, so the lifecycle tests no longer depend on host routes and run in restricted environments. - New tests cover that the event channel is not closed, the error is delivered exactly once, `Listen` returns the wrapped watcher error, and the unexpected-cancellation edge case. Verification: the new edge-case test fails against the previous implementation (`Listen() error = <nil>`) and passes with this change. The full package suite passes with `go test -race -count=1 ./client/internal/networkmonitor`, without requiring host routing access. ## Issue ticket number and link N/A ## Stack <!-- branch-stack --> Standalone PR based on `main`. ### Checklist - [x] Is it a bug fix - [ ] Is a typo/documentation fix - [ ] Is a feature enhancement - [ ] It is a refactor - [x] Created tests that fail without the change (if possible) - [x] This change does **not** modify the public API, gRPC protocols, functionality behavior, CLI / service flags, or introduce a new feature — **OR** I have discussed it with the NetBird team beforehand (link the issue / Slack thread in the description). See [CONTRIBUTING.md](https://github.com/netbirdio/netbird/blob/main/CONTRIBUTING.md#discuss-changes-with-the-netbird-team-first). > By submitting this pull request, you confirm that you have read and agree to the terms of the [Contributor License Agreement](https://github.com/netbirdio/netbird/blob/main/CONTRIBUTOR_LICENSE_AGREEMENT.md). ## Documentation Select exactly one: - [ ] I added/updated documentation for this change - [x] Documentation is **not needed** for this change (internal bug fix in the client's network monitor; no user-facing behavior, API, or configuration changes) ### Docs PR URL (required if "docs added" is checked) N/A <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Improved network monitoring error handling so watcher errors are reported reliably. * Preserved correct cancellation behavior when network watchers stop independently. * Prevented event channels from closing unexpectedly during monitoring. * **Tests** * Added coverage for watcher errors, cancellation scenarios, and event-channel behavior. * Improved test synchronization for more reliable results. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
saavagebueno added the pull-request label 2026-08-05 07:09:09 -04:00
Sign in to join this conversation.
No Label pull-request
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: DYNR/netbird#27734