Error Handling¶
The error-reporting layer has been extracted into the standalone
gitlab.com/phpboyscout/go/errorhandling
module. Its full documentation — the ErrorHandler interface, hints, exit codes
carried on the error value, LevelFatalQuiet, debug-gated stack traces, assertion
failures, the sentinels, and HelpConfig — now lives at:
API reference: pkg.go.dev/gitlab.com/phpboyscout/go/errorhandling.
See the migration note for
the import-path change and the Check signature change.
GTB imports the module directly (no adapter package). This page documents only what GTB layers on top.
The Execute wrapper — one funnel for every error¶
GTB's commands use Cobra's RunE and return errors idiomatically. A single wrapper in
pkg/cmd/root is where they all land:
Execute does four things the module cannot do for you:
- Sets
SilenceErrorsandSilenceUsageso Cobra never prints errors itself — all output comes from the structured logger. - Adds a
--helphint to flag-parse errors viaSetFlagErrorFunc. - Runs the command tree under a signal-aware context (see below).
- Routes whatever comes back through
ErrorHandler.CheckatLevelFatal.
The result: runtime errors, flag-parse errors, and PersistentPreRunE failures are all
reported the same way, and there is exactly one place in the process that exits.
Signal handling¶
Execute runs the command tree under a context cancelled by SIGINT/SIGTERM. The
first signal cancels gracefully; a second forces an immediate exit so a hung cleanup
cannot trap the user. The run exits 128+signum (130 for SIGINT, 143 for SIGTERM)
through the module's LevelFatalQuiet path — the correct code, logged at debug rather
than as an error, because an interrupt is a deliberate choice, not a failure.
Flush before the fatal call, not in a defer
Check(..., LevelFatal) exits the process, so deferred cleanup in the calling
frames never runs. GTB's telemetry flush is therefore sync.Once-guarded and
invoked explicitly before the fatal call, with its own bounded background context
— a cancelled context would abort the flush itself. Any pre-exit work you add must
follow the same pattern.
Help channels¶
The module defines the HelpConfig interface and deliberately ships no
implementations — where a team's support channel lives is a framework concern, not an
error library's. GTB provides the two common ones in pkg/props:
props.Tool{
Help: props.SlackHelp{Team: "Platform", Channel: "#platform-help"},
// or props.TeamsHelp{Team: "Platform", Channel: "Support"}
}
Scaffolded projects get this wired from gtb generate project --help-type slack|teams,
and the value round-trips through the project manifest.
Command patterns¶
Generated commands follow a fixed shape:
- Return errors; don't report them in place.
Executereports. AFatalburied in business logic skips deferred cleanup — see the module's reporting model. SetUsageis set per command. Generated commands callprops.ErrorHandler.SetUsage(cmd.Usage)in theirPreRunE, so a parent command that returnsErrRunSubCommandprints its own usage, not the root's.- A stubbed command returns
ErrNotImplemented(orNewErrNotImplemented(issueURL)to point at a tracking issue), which reports as a warning rather than a crash.
Related¶
- Module docs: errorhandling.go.phpboyscout.uk
- How-to: Write user-facing errors, Custom commands
- Patterns: Error handling patterns