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

  1. Change err.String() to err.Error() in the GetAll error branch at eBook/20.7.md:67.
  2. 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()).
  3. Compile-check the extracted snippet (go vet / go build) to flush out the other pre-Go 1 calls in the same function.
  4. 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

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


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.