Skip to content

feat(errors): add suggestions and options to errors#349

Merged
thde merged 2 commits intomainfrom
thde/wait
Feb 10, 2026
Merged

feat(errors): add suggestions and options to errors#349
thde merged 2 commits intomainfrom
thde/wait

Conversation

@thde
Copy link
Member

@thde thde commented Feb 9, 2026

Depends on: #348

This MR introduces a custom error that can be used to add context and suggestions. It also uses standardized exit codes:

❯ nctl get postgresdatabase
 ✗ No "PostgresDatabases" found 💥

Project: ninetest

Suggested actions:
  - List all PostgresDatabases in your organization: nctl get postgresdatabases --all-projects

❯ nctl auth set-project fsdddld
Warning: Project "fsdddld" does not exist in organization "ninedasdad", checking other organizations...

 ✗ Project "fsdddld" not found 💥

Available:
  - demian
  - nine-staging
  - ninetest

Suggested actions:
  - Project names always contain the organization name:
    nctl auth set-project <org>-<project>

@thde thde force-pushed the thde/wait branch 2 times, most recently from 0712aae to 06f7f37 Compare February 10, 2026 14:55
@thirdeyenick
Copy link
Contributor

Overall I really like the custom error and think it might be usable in one or the other place 👍

Copy link
Contributor

@thirdeyenick thirdeyenick left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@thde thde merged commit ca1ec03 into main Feb 10, 2026
3 checks passed
@thde thde deleted the thde/wait branch February 10, 2026 16:01
Comment on lines +10 to +17
const (
ExitOK = 0 // successful execution
ExitError = 1 // generic error
ExitUsageError = 80 // invalid input, validation errors
ExitForbidden = 83 // permission denied
ExitInternalError = 100 // bug in nctl
ExitUnavailable = 101 // API/service unreachable
)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that the biggest long-term risk is misclassification of errors.
People will start wrapping everything as a usage error because it looks nice.
Maybe we can provide here some rule of thumb, like:
usage error: user typo, missing flag, invalid value ...
forbidden: permission/auth ...
etc...

slices.Sort(available)

return cli.ErrorWithContext(fmt.Errorf("could not find context %q in kubeconfig", contextName)).
WithExitCode(cli.ExitUsageError).
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

some helpers here (under api/...) start returning internal/cli.Error directly. That's totally fine as our api is internal (for now). But it would be good to clarify this intention somewhere (and be consistent).
Or maybe we can have api return more semantic errors that get wrapped later?

}
}

func TestErrorOutput(t *testing.T) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With this MR, nctl error output becomes structured.
People will probably start depend on it at some point, e.g. shell scripts grepping output or tests asserting error messages. I don't mean we should lock it totally, but maybe we can check more stuff here, like: iteration order, emoji placement, spacing before/after, indentation of multi-line messages, etc...

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

Labels

None yet

Development

Successfully merging this pull request may close these issues.

3 participants