Error Handling & panics·Q294·Medium
In Go, error is an ordinary interface ( type error interface{ Error() string } ) returned as the last result. Failure paths are explicit in the signature and the control…
Error Handling & panics·Q295·Medium
a := errors.New("x") b := errors.New("x") fmt.Println(a == b) // false fmt.Println(a.Error() == b.Error()) // true type codeErr struct{ code int } func (e codeErr)…
Error Handling & panics·Q296·Medium
Both produce the same message text. %w also wraps : the returned error has an Unwrap() error method (or Unwrap() []error when there are several %w verbs, Go 1.20+), so…
Error Handling & panics·Q297·Medium
errors.Is(err, target) walks the error tree depth-first. At each node it returns true if the node == target (only when target's type is comparable) or if the node has an…
Error Handling & panics·Q298·Hard
errors.As(err, target any) bool finds the first error in the tree that is assignable to the type *target points at, stores it in *target , and returns true. A node can…
Error Handling & panics·Q299·Hard
errors.Join(errs ...error) (Go 1.20) returns an error that wraps every non-nil argument. It returns nil if all arguments are nil. Its message is the messages joined with…
Error Handling & panics·Q300·Medium
Sentinel ( var ErrNotFound = errors.New(...) ): a fixed value checked with errors.Is . It is simple and cheap, but it can't carry context, and it becomes part of your…
Error Handling & panics·Q301·Hard
A good custom error has structured fields, a message in lower case with no trailing punctuation, an Unwrap method if it wraps a cause, and usually a pointer receiver .…
Error Handling & panics·Q302·Hard
type MyErr struct{} func (*MyErr) Error() string { return "my err" } func do(fail bool) error { var p *MyErr // nil pointer if fail { p = &MyErr{} } return p // converts…
Error Handling & panics·Q303·Hard
== matches only the outermost error. As soon as someone wraps it with %w , the comparison fails. Use errors.Is , which walks the chain. The exceptions are documented…
Error Handling & panics·Q304·Hard
Wrap ( %w ) when callers need to inspect the cause and the cause is part of your stable contract. Don't wrap (use %v , or return your own error) when the cause is an…
Error Handling & panics·Q305·Medium
Panic when there is a programmer error or an impossible state that the caller can't reasonably handle: Violated invariants, such as an unreachable default in an…
Error Handling & panics·Q306·Hard
func helper() { if r := recover(); r != nil { fmt.Println("recovered:", r) } } func a() { defer helper(); panic("A") } // helper IS the deferred func func b() { defer…
Error Handling & panics·Q307·Hard
No. Panics are per goroutine. A panic unwinds only its own goroutine's stack. If nothing in that goroutine recovers, the whole process crashes, however many recovers sit…
Error Handling & panics·Q308·Hard
func main() { defer fmt.Println("1") defer func() { r := recover() fmt.Println("recovered", r) }() defer fmt.Println("3") fmt.Println(f()) panic("boom") } func f() (n…
Error Handling & panics·Q309·Medium
Use a named result and assign it inside a deferred function that calls recover . This is the only way a deferred function can change what the caller receives. func…
Error Handling & panics·Q310·Hard
Before Go 1.21, panic(nil) made recover() return nil , so code that tested if r := recover(); r != nil couldn't tell "no panic" from "panicked with nil" and swallowed…
Error Handling & panics·Q311·Hard
recover handles panics , both user panics and runtime-error panics (nil dereference, index out of range, nil map write, division by zero, failed type assertion, closing…
Error Handling & panics·Q312·Hard
Call Runs defers? Effect panic(v) Yes (current goroutine) Unwinds. Crashes with exit code 2 unless recovered. os.Exit(n) No Exits immediately with code n. Buffers aren't…
Error Handling & panics·Q313·Medium
Goroutines can't return values, so errors have to be passed back explicitly. golang.org/x/sync/errgroup is the standard tool. g.Go runs functions that return error .…
Error Handling & panics·Q314·Medium
Give each worker its own slot in a pre-sized slice. Each goroutine writes a different element, so there is no data race and no mutex. Then call errors.Join , which skips…
Error Handling & panics·Q315·Medium
The standard library leaves stacks out of errors on purpose: capturing them costs time, and well-written wrap messages usually give enough context. When you do need one:…
Error Handling & panics·Q316·Medium
Each error should be handled once. Handling means logging it, recovering from it (retry, fallback, default value), or turning it into a response. The alternative is to…
Error Handling & panics·Q317·Hard
For files opened for writing , Close (or the final flush) can be where the error shows up: buffered data, NFS, a full disk. defer f.Close() throws that error away, so…
Error Handling & panics·Q318·Medium
func parse(s string) error { var err error if s != "" { n, err := strconv.Atoi(s) // := declares a NEW err in this block if err == nil { fmt.Println("parsed", n) } }…
Error Handling & panics·Q319·Hard
It returns a non-nil error whose message is op: %!w(<nil>) . fmt.Errorf always returns a new error value, and it doesn't care whether the operand is nil. So an…
Error Handling & panics·Q320·Hard
ctx.Err() returns nil while the context is active. After it ends, it returns context.Canceled (from an explicit cancel) or context.DeadlineExceeded (from a timeout).…
Error Handling & panics·Q321·Medium
os.IsNotExist , os.IsExist and os.IsPermission were written before error wrapping existed. They unwrap only a fixed set of types ( *PathError , *LinkError ,…
Error Handling & panics·Q322·Medium
Instead of checking for a concrete type or sentinel, check whether the error implements a small interface that describes a behavior. The producer can then change its…
Error Handling & panics·Q323·Hard
http.Server recovers panics in each connection's goroutine. It logs the panic with a stack trace to ErrorLog and closes the connection, so the client gets a broken…
Error Handling & panics·Q324·Hard
A common senior-level design, inspired by Upspin and many internal Google and Uber codebases, is a single structured error type. It carries a machine-readable Kind (used…
Error Handling & panics·Q325·Hard
Read(p) can return n > 0 and a non-nil error in the same call, including io.EOF . The contract says callers should process the n bytes before looking at the error.…
Error Handling & panics·Q326·Medium
Any type with an Unwrap() error method is part of the chain. Without it, the wrapper is a dead end: errors.Is and errors.As stop at your type, and every caller checking…
Error Handling & panics·Q327·Hard
var ErrNotFound = errors.New("not found") type NotFoundError struct{ Name string } func (e *NotFoundError) Error() string { return e.Name + ": not found" } func (e…
Error Handling & panics·Q328·Hard
func main() { defer func() { fmt.Println("recovered:", recover()) }() defer func() { panic("second") }() panic("first") } Output: recovered: second . The new panic…
Error Handling & panics·Q329·Hard
With sync.Once , a panic in f still counts as "done". Do marks the Once as complete, the panic propagates to the first caller, and every later call returns immediately…
Error Handling & panics·Q330·Hard
Sentinel errors are created once at package init. Returning one is just copying an interface value, with no allocation. fmt.Errorf formats a string and allocates the…