mirror of
https://github.com/netbirdio/netbird.git
synced 2026-09-30 18:49:08 +02:00
[client] Classify the daemon's refusals in the GUI (review item 3)
FailedPrecondition reached the classifier unmatched, so a refusal showed as "Operation failed". It is the code both of the daemon's deliberate refusals carry: the update-settings kill switch, and a field an MDM policy manages. Both are now named — settings_locked and settings_managed_by_mdm, matched on the message the daemon composes — and FailedPrecondition itself falls back to change_refused, so a refusal the daemon grows later still reads as a refusal rather than a failure. Only the English strings are added. Bundle.Translate falls back to the default language for a missing key, so other locales show English until the usual translation pass, rather than the bare "error.<code>" the classifier would otherwise surface. Note: the package needs GTK4/WebKit to build, which this machine has not, so the test is type-checked (go vet, GOOS=windows) but was not executed locally; CI's Linux job runs it.
This commit is contained in:
@@ -134,6 +134,10 @@ func (c errorClassifier) classify(err error) *ClientError {
|
||||
strings.Contains(lower, "connection refused"),
|
||||
strings.Contains(lower, "context deadline exceeded"):
|
||||
code = "daemon_unreachable"
|
||||
case strings.Contains(lower, "update settings are disabled"):
|
||||
code = "settings_locked"
|
||||
case strings.Contains(lower, "managed by mdm"):
|
||||
code = "settings_managed_by_mdm"
|
||||
}
|
||||
|
||||
// Fall back to the gRPC status code when the message didn't match a known
|
||||
@@ -145,6 +149,11 @@ func (c errorClassifier) classify(err error) *ClientError {
|
||||
code = "permission_denied"
|
||||
case gcodes.Unavailable, gcodes.DeadlineExceeded:
|
||||
code = "daemon_unreachable"
|
||||
case gcodes.FailedPrecondition:
|
||||
// The daemon answered and refused. The two refusals it composes
|
||||
// are matched above; anything else that reaches here is still a
|
||||
// refusal, so say that rather than "operation failed".
|
||||
code = "change_refused"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -34,6 +34,28 @@ func TestErrorClassifier_Classify(t *testing.T) {
|
||||
require.Equal(t, "session_expired", ce.Code)
|
||||
})
|
||||
|
||||
t.Run("the update-settings kill switch is a refusal, not a failure", func(t *testing.T) {
|
||||
err := gstatus.Error(gcodes.FailedPrecondition,
|
||||
"update settings are disabled, you cannot use this feature without update settings enabled")
|
||||
|
||||
ce := c.classify(err)
|
||||
require.NotNil(t, ce)
|
||||
require.Equal(t, "settings_locked", ce.Code)
|
||||
})
|
||||
|
||||
t.Run("an MDM-managed field is named as such", func(t *testing.T) {
|
||||
err := gstatus.Error(gcodes.FailedPrecondition,
|
||||
"fields managed by MDM cannot be modified: [managementURL]")
|
||||
|
||||
require.Equal(t, "settings_managed_by_mdm", c.classify(err).Code)
|
||||
})
|
||||
|
||||
t.Run("any other refusal is still a refusal", func(t *testing.T) {
|
||||
// FailedPrecondition means the daemon answered and declined; falling
|
||||
// through to "unknown" showed "Operation failed" instead.
|
||||
require.Equal(t, "change_refused", c.classify(gstatus.Error(gcodes.FailedPrecondition, "something else")).Code)
|
||||
})
|
||||
|
||||
t.Run("unavailable code maps to daemon_unreachable", func(t *testing.T) {
|
||||
ce := c.classify(gstatus.Error(gcodes.Unavailable, "transport closing"))
|
||||
require.Equal(t, "daemon_unreachable", ce.Code)
|
||||
|
||||
Reference in New Issue
Block a user