Files
probo/.cursor/rules/go-error-handling.mdc
Émile Ré 8f8f09008a Version Cursor rules
Track .cursor/rules/ in git so coding conventions are shared
across the team. Everything else under .cursor/ stays ignored.

Signed-off-by: Émile Ré <emile@probo.com>
2026-05-19 14:10:39 +04:00

47 lines
983 B
Plaintext

---
description: Go error handling — wrap with fmt.Errorf, always name err, use errors.AsType
globs: "**/*.go"
alwaysApply: false
---
# Go error handling
## Wrapping
- Error variables are always named `err`
- When a function returns errors from multiple call sites, each must be wrapped
- Wrap with `fmt.Errorf("cannot ...: %w", err)` — lowercase, starts with `cannot`
- Each wrap message in a function must be distinct
```go
// GOOD
foo, err := s.loadFoo(ctx)
if err != nil {
return fmt.Errorf("cannot load foo: %w", err)
}
bar, err := s.loadBar(ctx, foo.ID)
if err != nil {
return fmt.Errorf("cannot load bar: %w", err)
}
// BAD — bare return without wrapping
foo, err := s.loadFoo(ctx)
if err != nil {
return err
}
```
## Type assertions on errors
Use `errors.AsType[T](err)` (generic form), not `errors.As(err, &ptr)`:
```go
// GOOD
if e, ok := errors.AsType[*ValidationError](err); ok { ... }
// BAD
var ve *ValidationError
if errors.As(err, &ve) { ... }
```