Page:
Error Handling
No results
1
Error Handling
Virgil edited this page 2026-02-23 04:54:00 +00:00
Error Handling
Error Creation
// Simple error (replaces fmt.Errorf)
return cli.Err("invalid model: %s", name)
// Wrap with context (nil-safe)
return cli.Wrap(err, "load config") // "load config: <original>"
// Wrap with i18n grammar
return cli.WrapVerb(err, "load", "config") // "Failed to load config: <original>"
return cli.WrapAction(err, "connect") // "Failed to connect: <original>"
Error Inspection
Re-exports of errors package for convenience:
if cli.Is(err, os.ErrNotExist) { ... }
var exitErr *cli.ExitError
if cli.As(err, &exitErr) {
os.Exit(exitErr.Code)
}
combined := cli.Join(err1, err2, err3)
Exit Codes
// Return specific exit code from a command
return cli.Exit(2, fmt.Errorf("validation failed"))
The ExitError type is checked in Main() — commands that return *ExitError cause the process to exit with that code.
Fatal Functions (Deprecated)
These exist for legacy code but should not be used in new commands. Return errors from RunE instead.
// DON'T use these in new code:
cli.Fatal(err) // prints + os.Exit(1)
cli.Fatalf("bad: %v", err) // prints + os.Exit(1)
cli.FatalWrap(err, "load config") // prints + os.Exit(1)
cli.FatalWrapVerb(err, "load", "x") // prints + os.Exit(1)
Pattern: Commands Return Errors
// GOOD: return error, let Main() handle exit
func runBuild(cmd *cli.Command, args []string) error {
if err := compile(); err != nil {
return cli.WrapVerb(err, "compile", "project")
}
cli.Success("Build complete")
return nil
}
// BAD: calling os.Exit from library code
func runBuild(cmd *cli.Command, args []string) error {
if err := compile(); err != nil {
cli.Fatal(err) // DON'T DO THIS
}
return nil
}