go:errors:error_wrapping
Differences
This shows you the differences between two versions of the page.
| Next revision | Previous revision | ||
| go:errors:error_wrapping [2026/01/05 23:17] – created phong2018 | go:errors:error_wrapping [2026/01/05 23:22] (current) – phong2018 | ||
|---|---|---|---|
| Line 24: | Line 24: | ||
| * Use `%v` if you only want formatting without wrapping. | * Use `%v` if you only want formatting without wrapping. | ||
| * Wrapping enables `errors.Is` and `errors.As` to work through layers. | * Wrapping enables `errors.Is` and `errors.As` to work through layers. | ||
| + | |||
| + | ===== Error wrapping (%w) vs formatting (%v) ===== | ||
| + | |||
| + | ==== What is it? ==== | ||
| + | In `fmt.Errorf`, | ||
| + | * `%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 ==== | ||
| + | <code go> | ||
| + | package main | ||
| + | |||
| + | import ( | ||
| + | " | ||
| + | " | ||
| + | ) | ||
| + | |||
| + | var ErrNotFound = errors.New(" | ||
| + | |||
| + | func repo() error { | ||
| + | return ErrNotFound | ||
| + | } | ||
| + | |||
| + | // Wrap with %w (keeps original error) | ||
| + | func usecaseWrap() error { | ||
| + | if err := repo(); err != nil { | ||
| + | return fmt.Errorf(" | ||
| + | } | ||
| + | return nil | ||
| + | } | ||
| + | |||
| + | // Format only with %v (does NOT wrap) | ||
| + | func usecaseFormatOnly() error { | ||
| + | if err := repo(); err != nil { | ||
| + | return fmt.Errorf(" | ||
| + | } | ||
| + | return nil | ||
| + | } | ||
| + | |||
| + | func main() { | ||
| + | errW := usecaseWrap() | ||
| + | errV := usecaseFormatOnly() | ||
| + | |||
| + | fmt.Println(" | ||
| + | fmt.Println(" | ||
| + | fmt.Println(" | ||
| + | |||
| + | fmt.Println(" | ||
| + | fmt.Println(" | ||
| + | fmt.Println(" | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ==== Example output ==== | ||
| + | < | ||
| + | == %w == | ||
| + | Error: usecase (wrap): not found | ||
| + | errors.Is(errW, | ||
| + | |||
| + | == %v == | ||
| + | Error: usecase (format only): not found | ||
| + | errors.Is(errV, | ||
| + | </ | ||
| + | |||
| + | ==== Rule of thumb ==== | ||
| + | * Use `%w` when you want callers to detect the original error using `errors.Is/ | ||
| + | * Use `%v` when you only want a formatted message and do not need error matching. | ||
| + | |||
| + | ==== Related pages ==== | ||
| + | * [[go: | ||
| + | * [[go: | ||
| + | * [[go: | ||
| ==== Hard words (English) ==== | ==== Hard words (English) ==== | ||
| * **wrap** /ræp/: bọc | * **wrap** /ræp/: bọc | ||
| - | * **preserve** /prɪˈzɝːv/: giữ lại | + | * **format** /ˈfɔːrmæt/: định dạng |
| * **root cause** /ruːt kɔːz/: nguyên nhân gốc | * **root cause** /ruːt kɔːz/: nguyên nhân gốc | ||
| + | * **detect** / | ||
| + | * **matching** / | ||
| + | * **preserve** / | ||
| * **layer** / | * **layer** / | ||
go/errors/error_wrapping.1767655060.txt.gz · Last modified: by phong2018
