Skip to content

Provider error messages use four different prefix conventions #565

Description

@retr0h

A provider's errors surface in job results, the audit log and the CLI. They read as four different systems.

What is there

sysctl        "sysctl create: ..."               <domain> <verb>
netplan       "netplan apply: ..."               <domain> <verb>
ntp           "ntp: ..."                         <domain>
service       "service: ..."                     <domain>
certificate   "create certificate: ..."          <verb> <domain>
cron          "create cron entry: ..."           <verb> <domain>
file          "failed to execute template: ..."  failed to <verb>
user          "chpasswd failed: ..."             <command> failed

Reproduce:

for d in node/sysctl node/ntp node/user node/service node/certificate \
         scheduled/cron file network/netplan; do
  printf '%-20s ' "$d"
  grep -rho 'fmt.Errorf("[a-z][a-z ]*:' internal/provider/$d/*.go \
    | sed 's/fmt.Errorf("//' | sort -u | head -3 | tr '\n' ' '
  echo
done

Why it matters beyond tidiness

file's failed to ... prefix is the one worth changing on its own merits. These errors are almost always wrapped by a caller, so the rendered string becomes "deploy cron entry: failed to execute template: ...". Go's own guidance is that error strings do not announce failure, because the context does.

user's chpasswd failed: names the command rather than the operation, which leaks the implementation into a message a CLI user reads.

Not in scope

The sentinel errors are already consistent and should stay as they are:

ErrUnsupported  = errors.New("operation not supported on this OS family")
ErrNotFound     = errors.New("not found")
ErrNotManaged   = errors.New("not managed by osapi")
ErrNotInstalled = errors.New("not installed")

So is wrapping with %w, which every provider does on the paths that carry a cause. #536 fixed the one place that did not.

Suggested convention

<domain> <verb>: <what went wrong>, which is what sysctl and netplan already use and which sorts and greps well:

sysctl create: key must not be empty
cron delete: not managed by osapi
file deploy: execute template: ...

Picking one and applying it is the whole change. It should be settled in components/osapi/providers.md first so new providers inherit it rather than copying whichever neighbour they read.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions