Skip to content

Structure errors as Title/Reason/Status/Next step, name exit codes - #1961

Open
DO-rrao wants to merge 1 commit into
rrao/welcome-screenfrom
rrao/error-format-and-exit-codes
Open

DO-rrao wants to merge 1 commit into
rrao/welcome-screenfrom
rrao/error-format-and-exit-codes

Conversation

@DO-rrao

@DO-rrao DO-rrao commented Sep 15, 2026

Copy link
Copy Markdown
Contributor

Summary

  • checkErr now resolves every error to a StructuredError (an explicit implementation, or a genericStructuredError synthesized from a new status-code table) and renders Title → Reason → Status → Next step as separate lines, mirroring the same four fields into the JSON error envelope additively (detail unchanged for existing consumers).
  • Adds commands/error_codes.go: canned reason + a run <command> next step for common API status codes (400/401/403/404/409/422/429/5xx), so Style.Hint bolds the whole suggestion consistently.
  • FlagValidationError implements the new interface for its JSON output while keeping its own richer per-flag text block untouched.
  • Names the two exit codes doctl has always used (exitGeneralError = 1, exitUsageError = 255) instead of magic numbers, and routes the config-read failure through checkErr instead of a raw log.Fatalln, so it gets consistent formatting and a controlled exit code.
  • Fixes a pre-existing compile bug in auth.go's writeConfig(), which referenced an out-of-scope context identifier; it's now a parameter from its one call site.

Test plan

  • go build ./cmd/doctl succeeds
  • go vet ./commands/... ./internal/... clean
  • go test ./commands/... — existing checkErr/FlagValidationError tests pass unchanged (one pre-existing, unrelated failure: TestRenderWelcomeUsesASCIIGlyphsWhenRequired, confirmed to fail identically without these changes)
  • Manually verified: 404/text, 404/JSON, missing-flags/text, missing-flags/JSON, unknown command (exit 255), success path (exit 0), corrupt config file (exit 1, styled instead of raw crash), forced-PTY color/bold rendering

🤖 Generated with Claude Code

checkErr now resolves every error to a StructuredError (an explicit
implementation, or a genericStructuredError synthesized from the
status-code table) and renders Title, Reason, Status and Next step as
separate lines, mirroring the same four fields into the JSON error
envelope additively (detail is unchanged). FlagValidationError
implements the interface for its JSON output while keeping its own
richer text block.

Adds an error-code table (error_codes.go) for common API status codes
(400/401/403/404/409/422/429/5xx), each with a canned reason and a
"run <command>" next step so Style.Hint bolds the whole suggestion.

Names the two exit codes doctl has always used (exitGeneralError=1,
exitUsageError=255) instead of magic numbers, and routes the
config-read failure through checkErr instead of a raw log.Fatalln so
it gets the same formatting and a controlled exit code.

Also fixes a pre-existing bug in auth.go's writeConfig(), which
referenced an out-of-scope `context` identifier and could not compile;
it's now a parameter from its one call site.
Comment thread commands/auth.go
Comment on lines 346 to +347
notice("Now using context [%s] by default", context)
return writeConfig()
return writeConfig(context)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

We are printing the success message twice: notice above and fmt.Printf in writeConfig L362

@SSharma-10

Copy link
Copy Markdown
Contributor

Build looks good now, but the auth switch is still broken.

Locally, go test ./commands/ is failing with context does not exist in:

  • TestAuthSwitchPersistsOnlyTheContext
  • TestAuthForcesLowercase

Looks like RunAuthSwitch is still checking viper while writeConfig checks the YAML file, so they are out of sync. Can you wire the switch through the file-based path as well?

@SSharma-10

Copy link
Copy Markdown
Contributor

Tried this locally:

doctl compute droplet get 999999999

Text only shows "Not Found" + the canned reason, the actual API message only shows up in json detail.
Also for a 404, suggesting doctl auth list feels off

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants