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

  1. Keep the declaration at package level exactly as shown so identity comparison works, and export it (ErrNotFound) if callers live in another package
  2. Compare with errors.Is(err, ErrNotFound), never by string, so wrapping with %w still matches
  3. Return the same sentinel from every miss path in the package so callers have exactly one case to handle
  4. 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

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


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.