Skip to main content

Error Handling

Decision matrix

Default error-handling rules

Default error-handling rules.
RuleExpected defaultAvoid
Use guard clausesReturn early on failure and keep the happy path unindented.Nesting success logic inside if err == nil branches.
Check Kubernetes error types explicitlyHandle NotFound and similar typed API failures with apierrors helpers.String-matching Kubernetes errors.
Define checkable sentinels only for real control flowExpose well-known errors when callers truly need errors.Is behavior.Creating exported errors for every failure string in the codebase.
Do not panic in controllersReturn an error or surface an internal invariant failure explicitly.Panics that can crash operator management for every cluster.

Wrapping and context

if err := r.Client.Create(ctx, secret); err != nil {
return fmt.Errorf("create bootstrap secret %s/%s: %w", secret.Namespace, secret.Name, err)
}

Kubernetes typed errors

if err := r.Client.Get(ctx, key, secret); err != nil {
if apierrors.IsNotFound(err) {
return r.createSecret(ctx, ...)
}

return fmt.Errorf("get secret %s: %w", key.Name, err)
}

Checkable internal errors

Use exported sentinel errors only when the caller genuinely needs to branch on the result:

var (
ErrClusterLocked = errors.New("cluster is locked")
ErrNoLeader = errors.New("no leader available")
)
No panics in controller or internal logic paths

If a nil or impossible state appears, return a contextual error and let the caller decide how to surface it. A panic in a reconcile worker can take down management for the entire operator process.

Related coding rules

Next release documentation

You are reading the unreleased main docs. Use the version menu for the newest published release, or check the release notes for what is already out.

Was this page helpful?

Use Needs work to open a structured GitHub issue for this page. The Yes button only acknowledges the signal locally.