Go Style
This document captures local Go conventions. It is normative and minimal.
For everything not covered here, follow uber-go/guide. :contentReference[oaicite:1]{index=1}
Errors
Err Checks
- Do not write
if err := f(); err != nil { ... }. - Separate call and check into two statements.
Wrapping
- Wrap errors only when adding new actionable context.
- Do not wrap with repetitive or duplicate information.
- Use
%wfor wrapping. - Do not restate underlying identifiers the callee already logs.
Format
- Wrapping message format:
doing X (id=..., name=...): %w - Keep lowercase, no punctuation, no “failed to”.
Inspection
- Use
errors.Isanderrors.Asfor inspection in our own code. - Define sentinel errors for inspectable cases:
var ErrFoo = errors.New(...).
Logging
- Use only
log/slog. - Do not log an error then return it unchanged.
- Use structured logs (attributes, not formatted strings).
- Libraries may accept loggers via options.
Formatting
When a log call has multiple attributes, place each on its own line:
// Good
slog.Info("recv",
slog.String("type", "SecurityTypes"),
slog.Int("count", int(b[0])),
slog.String("raw", fmt.Sprintf("%x", b)))
// Bad - line too long
slog.Info("recv", slog.String("type", "SecurityTypes"), slog.Int("count", int(b[0])), slog.String("raw", fmt.Sprintf("%x", b)))
Single-attribute calls may stay on one line if short:
slog.Info("bell received")
slog.Warn("watcher error", slog.String("error", err.Error()))
HTTP
- Do not use HTTP frameworks.
- Use
net/httpdirectly.