unknwon/the-way-to-go_ZH_CN · error
err.String()
Error message
err.String()
What it means
err.String() references a method removed in Go 1.0 (2012). Pre-Go 1, datastore errors were os.Error values with String(); the modern error interface defines only Error() string. The GetAll error branch of root() therefore fails to compile under any current toolchain with `err.String undefined (type error has no field or method String)`, even though the surrounding datastore query code is otherwise well-formed.
Source
Thrown at eBook/20.7.md:67
var guestbookTemplate = template.Must(template.New("book").Parse(guestbookTemplateHTML))
type Greeting struct {
Author string
Content string
Date datastore.Time
}
func init() {
http.HandleFunc("/", root)
http.HandleFunc("/sign", sign)
}
func root(w http.ResponseWriter, r *http.Request) {
c := appengine.NewContext(r)
q := datastore.NewQuery("Greeting").Order("-Date").Limit(10)
greetings := make([]Greeting, 0, 10)
if _, err := q.GetAll(c, &greetings); err != nil {
http.Error(w, err.String(), http.StatusInternalServerError)
return
}
if err := guestbookTemplate.Execute(w, greetings); err != nil {
http.Error(w, err.String(), http.StatusInternalServerError)
}
}
func sign(w http.ResponseWriter, r *http.Request) {
c := appengine.NewContext(r)
g := Greeting{
Content: r.FormValue("content"),
Date: datastore.SecondsToTime(time.Seconds()),
}
if u := user.Current(c); u != nil {
g.Author = u.String()
}
_, err := datastore.Put(c, datastore.NewIncompleteKey(c, "Greeting", nil), &g)
if err != nil {View on GitHub (pinned to 7a54d34d36)
Solutions
- Change err.String() to err.Error() in the GetAll error branch at eBook/20.7.md:67.
- Update the rest of the snippet to Go 1 + google.golang.org/appengine idioms: fetch the context, keep the query, and use time.Time for Greeting.Date instead of datastore.SecondsToTime(time.Seconds()).
- Compile-check the extracted snippet (go vet / go build) to flush out the other pre-Go 1 calls in the same function.
- In CI, build every code block from the eBook against the current Go release so stale APIs are flagged before publication.
Example fix
// before
if _, err := q.GetAll(c, &greetings); err != nil {
http.Error(w, err.String(), http.StatusInternalServerError)
return
}
// after
if _, err := q.GetAll(c, &greetings); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
} Defensive patterns
Strategy: validation
Validate before calling
// Before trusting a legacy snippet, compile it — go vet turns
// `err.String undefined (type error has no field or method String)`
// into a CI failure instead of a runtime surprise:
func validateSnippet(dir string) error {
cmd := exec.Command("go", "vet", "./...")
cmd.Dir = dir
if out, err := cmd.CombinedOutput(); err != nil {
return fmt.Errorf("guestbook sample does not compile: %s", out)
}
return nil
} Type guard
// narrows whether the value exposes the legacy String() method
func hasLegacyString(err error) bool {
_, ok := err.(interface{ String() string })
return ok
} Try / catch
// Go's error handling for datastore reads — always err.Error(), always return:
if _, err := q.GetAll(c, &greetings); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
} Prevention
- Memorize the Go 1 error contract: only Error() string exists on error.
- Run go vet/staticcheck (or gopls diagnostics) on snippets; they flag undefined methods instantly.
- Build every datastore sample in CI against the current google.golang.org/appengine module.
- Never copy query/error-handling blocks from pre-2012 tutorials without compiling them first.
When it happens
Trigger: Running go build/vet on the root handler from eBook/20.7.md: `q := datastore.NewQuery("Greeting").Order("-Date").Limit(10)` then `if _, err := q.GetAll(c, &greetings); err != nil` — GetAll returns ([]*datastore.Key, error), and the branch calls err.String(), which does not exist on error. Compilation aborts at line 67.
Common situations: Following chapter 20 of this eBook (a Chinese Go book written against the 2011 App Engine SDK). Developers who paste the guestbook query sample into a Go 1+ module, or who restore archived GAE projects, hit this alongside its siblings: time.Seconds(), datastore.SecondsToTime, and u.String() on *user.User all date from the same pre-Go 1 era (some were later re-added as different APIs).
Related errors
- err.String()
- math - square root of negative number
- Not found error
- math: square root of negative number %g
- err.String()
AI-assisted analysis of unknwon/the-way-to-go_ZH_CN@7a54d34d36 (2026-08-15).
Data as JSON: /api/errors/5f6a922ae183f113.
Report an issue: GitHub.