unknwon/the-way-to-go_ZH_CN · info
Not found error
Error message
Not found error
What it means
Package-level sentinel error from section 13.1's errors.go example: var errNotFound error = errors.New("Not found error"). It demonstrates the Go idiom of declaring one shared error value at package scope so every lookup miss returns the identical value, letting callers compare with err == errNotFound (or errors.Is) instead of matching message text. The example main only prints it (fmt.Printf("error: %v", errNotFound)).
Source
Thrown at eBook/13.1.md:34
```go
err := errors.New("math - square root of negative number")
```
在示例 13.1 中你可以看到一个简单的用例:
示例 13.1 [errors.go](examples/chapter_13/errors.go):
```go
// errors.go
package main
import (
"errors"
"fmt"
)
var errNotFound error = errors.New("Not found error")
func main() {
fmt.Printf("error: %v", errNotFound)
}
// error: Not found error
```
可以把它用于计算平方根函数的参数测试:
```go
func Sqrt(f float64) (float64, error) {
if f < 0 {
return 0, errors.New ("math - square root of negative number")
}
// implementation of Sqrt
}
```
View on GitHub (pinned to 7a54d34d36)
Solutions
- Keep the declaration at package level exactly as shown so identity comparison works, and export it (ErrNotFound) if callers live in another package
- Compare with errors.Is(err, ErrNotFound), never by string, so wrapping with %w still matches
- Return the same sentinel from every miss path in the package so callers have exactly one case to handle
- If the message appears unexpectedly in logs, audit callers that print err without distinguishing not-found from real failures
Example fix
// before: sentinel trapped inside the function, new value each call
func Find(k string) (*Item, error) {
errNotFound := errors.New("Not found error")
// ...
return nil, errNotFound
}
// after: one exported package-level sentinel
var ErrNotFound = errors.New("Not found error")
func Find(k string) (*Item, error) {
// ...
return nil, ErrNotFound
} Defensive patterns
Strategy: type-guard
Type guard
var ErrNotFound = errors.New("Not found error")
func IsNotFound(err error) bool {
return errors.Is(err, ErrNotFound)
} Try / catch
item, err := Find(key)
if err != nil {
if errors.Is(err, ErrNotFound) {
// absence is a normal outcome: empty result, 404, or default
return Item{}, nil
}
return Item{}, err // real failure
} Prevention
- Declare sentinel errors once at package level, exported if cross-package; never inside the function
- Compare with errors.Is or ==, never err.Error() string matching
- Wrap with %w when adding context so sentinel checks still succeed
- Handle the not-found branch separately from infrastructure failures at every call site
When it happens
Trigger: The printed demo never fires it; it becomes a runtime error once you follow the book's next step and return errNotFound from a lookup function when the sought key/element is absent — e.g. the Sqrt parameter test or a map/slice Find that reaches its miss branch.
Common situations: Key lookups in caches and config maps; repository-style Find functions returning (T, error); the classic beginner mistake of declaring the sentinel inside the function (new allocation per call) so == comparison stops working; keeping it lowercase (errNotFound) so other packages cannot reference it.
Related errors
- math - square root of negative number
- key not found
- math: square root of negative number %g
- err.String()
- err.String()
AI-assisted analysis of unknwon/the-way-to-go_ZH_CN@7a54d34d36 (2026-08-15).
Data as JSON: /api/errors/1b3f143fe05ae155.
Report an issue: GitHub.