Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions internal/cli/errorhint_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,31 @@ func TestErrorHint(t *testing.T) {
ae: &coreapi.APIError{Status: 400, Code: "destination_loops", Extra: map[string]any{"target": "a@x.test"}},
want: "routes back here",
},
{
name: "run_cooldown with retryAfter seconds",
ae: &coreapi.APIError{Status: 429, Code: "run_cooldown", Extra: map[string]any{"retryAfter": float64(45)}},
want: "wait 45 seconds before fetching again",
},
{
name: "run_cooldown without retryAfter still hints",
ae: &coreapi.APIError{Status: 429, Code: "run_cooldown"},
want: "maximum once per minute",
},
{
name: "pickup_limit_reached with limit",
ae: &coreapi.APIError{Status: 409, Code: "pickup_limit_reached", Extra: map[string]any{"limit": float64(10)}},
want: "reached the limit of 10 pickup sources",
},
{
name: "source_is_self explains self-fetch prohibition",
ae: &coreapi.APIError{Status: 400, Code: "source_is_self"},
want: "cannot fetch from this mailbox itself",
},
{
name: "duplicate_source names existing source",
ae: &coreapi.APIError{Status: 409, Code: "duplicate_source"},
want: "already exists on this mailbox",
},
{
name: "unrelated code gets no hint",
ae: &coreapi.APIError{Status: 400, Code: "validation_failed"},
Expand Down
24 changes: 24 additions & 0 deletions internal/cli/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,30 @@ func errorHint(ae *coreapi.APIError) string {
return fmt.Sprintf("%s reaches more than one recipient here (a group, an alias, a webhook, or a route that forwards on) — nobody there can answer the code, and the disable link would stop your forwarding for whoever clicked it first; name one person's address", tgt)
}
return "that address reaches more than one recipient here (a group, an alias, a webhook, or a route that forwards on) — nobody there can answer the code, and the disable link would stop your forwarding for whoever clicked it first; name one person's address"
case "run_cooldown":
if ra, ok := ae.Extra["retryAfter"]; ok {
switch v := ra.(type) {
case float64:
return fmt.Sprintf("pickup is on cooldown (maximum once per minute) — please wait %d seconds before fetching again", int(v))
case int:
return fmt.Sprintf("pickup is on cooldown (maximum once per minute) — please wait %d seconds before fetching again", v)
}
}
return "pickup is on cooldown (maximum once per minute) — please wait before fetching again"
case "pickup_limit_reached":
if lim, ok := ae.Extra["limit"]; ok {
switch v := lim.(type) {
case float64:
return fmt.Sprintf("this mailbox has reached the limit of %d pickup sources", int(v))
case int:
return fmt.Sprintf("this mailbox has reached the limit of %d pickup sources", v)
}
}
return "this mailbox has reached the maximum number of pickup sources"
case "source_is_self":
return "cannot fetch from this mailbox itself — pickup is for consolidating mail from other mailboxes or external providers"
case "duplicate_source":
return "a pickup source for this server and username already exists on this mailbox"
}
return ""
}
Expand Down
Loading