go:errors:error_wrapping
Table of Contents
Error wrapping (%w)
What is it?
Error wrapping means adding context to an error while keeping the original error inside it.
In Go, `fmt.Errorf` supports wrapping using `%w`:
fmt.Errorf("doing X: %w", err)
What is it used for?
- Add helpful context at each layer (repo → usecase → handler).
- Preserve the root cause so callers can detect it with `errors.Is/As`.
Example
if err := dbCall(); err != nil { return fmt.Errorf("update user: %w", err) }
Notes / pitfalls
- Use `%w` only once in a single `fmt.Errorf` call.
- Use `%v` if you only want formatting without wrapping.
- Wrapping enables `errors.Is` and `errors.As` to work through layers.
Error wrapping (%w) vs formatting (%v)
What is it?
In `fmt.Errorf`, you can use:
- `%w` to wrap an error (keeps the original error inside)
- `%v` to format an error (string formatting only; does NOT wrap)
Why it matters
- `%w` enables `errors.Is` / `errors.As` to find the root cause through wrapped layers.
- `%v` only prints the error message; `errors.Is` will not match the original error.
Example code
package main import ( "errors" "fmt" ) var ErrNotFound = errors.New("not found") func repo() error { return ErrNotFound } // Wrap with %w (keeps original error) func usecaseWrap() error { if err := repo(); err != nil { return fmt.Errorf("usecase (wrap): %w", err) } return nil } // Format only with %v (does NOT wrap) func usecaseFormatOnly() error { if err := repo(); err != nil { return fmt.Errorf("usecase (format only): %v", err) } return nil } func main() { errW := usecaseWrap() errV := usecaseFormatOnly() fmt.Println("== %w ==") fmt.Println("Error:", errW) fmt.Println("errors.Is(errW, ErrNotFound):", errors.Is(errW, ErrNotFound)) fmt.Println("\n== %v ==") fmt.Println("Error:", errV) fmt.Println("errors.Is(errV, ErrNotFound):", errors.Is(errV, ErrNotFound)) }
Example output
== %w == Error: usecase (wrap): not found errors.Is(errW, ErrNotFound): true == %v == Error: usecase (format only): not found errors.Is(errV, ErrNotFound): false
Rule of thumb
- Use `%w` when you want callers to detect the original error using `errors.Is/As`.
- Use `%v` when you only want a formatted message and do not need error matching.
Related pages
Hard words (English)
- wrap /ræp/: bọc
- format /ˈfɔːrmæt/: định dạng
- root cause /ruːt kɔːz/: nguyên nhân gốc
- detect /dɪˈtekt/: phát hiện/nhận biết
- matching /ˈmætʃɪŋ/: so khớp
- preserve /prɪˈzɝːv/: giữ lại
- layer /ˈleɪər/: tầng
go/errors/error_wrapping.txt · Last modified: by phong2018
