unknwon/the-way-to-go_ZH_CN · error
err.String()
Error message
err.String()
What it means
err.String() invokes a method that does not exist on Go's built-in error interface. This snippet was written against pre-Go 1 (2011) releases, where errors were the os.Error type carrying a String() method; since Go 1.0 (2012) the error interface exposes only Error() string. Any modern gc toolchain rejects the sample at compile time with `err.String undefined (type error has no field or method String)`, so the sign handler in section 20.6 cannot even build.
Source
Thrown at eBook/20.6.md:53
`
var signTemplate = template.Must(template.New("sign").Parse(signTemplateHTML))
func init() {
http.HandleFunc("/", root)
http.HandleFunc("/sign", sign)
}
func root(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "text/html")
fmt.Fprint(w, guestbookForm)
}
func sign(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "text/html")
err := signTemplate.Execute(w, r.FormValue("content"))
if err != nil {
http.Error(w, err.String(), http.StatusInternalServerError)
}
}
```
## 链接
- [目录](directory.md)
- 上一节:[使用用户服务和探索其 API](20.5.md)
- 下一节:[使用数据存储](20.7.md)
View on GitHub (pinned to 7a54d34d36)
Solutions
- Replace err.String() with err.Error() in the http.Error call at eBook/20.6.md:53 — that is the only method the error interface has.
- Migrate the sibling pre-Go 1 APIs in the same chapter so the sample compiles: import google.golang.org/appengine/{http, user, datastore}, and update calls like time.Seconds()/datastore.SecondsToTime to time.Now().
- Verify with a modern toolchain: gofmt, then go vet / go build on the extracted snippet; add a return after http.Error so the handler stops on template failure.
- Longer term, generate eBook snippets from real compiled sources and build them in CI so doc code cannot drift from the current Go API.
Example fix
// before
err := signTemplate.Execute(w, r.FormValue("content"))
if err != nil {
http.Error(w, err.String(), http.StatusInternalServerError)
}
// after
err := signTemplate.Execute(w, r.FormValue("content"))
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
} Defensive patterns
Strategy: validation
Validate before calling
// Fail the docs build if any snippet still uses the pre-Go 1 error API.
// Run over extracted .go snippets or the markdown source:
func snippetsUseDeadErrorAPI(files []string) error {
for _, f := range files {
b, err := os.ReadFile(f)
if err != nil {
return err
}
if strings.Contains(string(b), "err.String()") {
return fmt.Errorf("%s: err.String() was removed in Go 1; use err.Error()", f)
}
}
// ultimate check: the snippet must actually compile
if out, err := exec.Command("go", "vet", "./...").CombinedOutput(); err != nil {
return fmt.Errorf("snippet does not compile: %s", out)
}
return nil
} Type guard
// stringerError reports whether err still carries the pre-Go 1 String() method.
func stringerError(err error) bool {
_, ok := err.(interface{ String() string })
return ok
} Try / catch
// Go has no try/catch; check the error inline and format it with Error():
if err := signTemplate.Execute(w, r.FormValue("content")); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return // stop the handler; Execute already wrote partial output
} Prevention
- Treat the error interface as having exactly one method, Error() string; String() belongs to fmt.Stringer and to pre-Go 1 os.Error.
- Compile and go vet every code sample before publishing; undefined methods are caught at build time for free.
- Extract book snippets into real .go files built by CI so they cannot drift from the current Go release.
- When porting old App Engine samples, migrate wholesale to google.golang.org/appengine and Go 1 idioms instead of patching single lines.
- Prefer current go.dev documentation over mirrors of 2011 tutorials.
When it happens
Trigger: Compiling the sign handler from eBook/20.6.md: `err := signTemplate.Execute(w, r.FormValue("content"))` returns the built-in error interface, then the error branch calls `http.Error(w, err.String(), http.StatusInternalServerError)`. go build / go vet / gopls on this snippet fails immediately with an undefined-method error.
Common situations: Copying code from tutorials or eBooks written before Go 1.0 — this chapter targets the 2011 App Engine SDK (appengine.NewContext, datastore.SecondsToTime, time.Seconds, all likewise removed or changed). Mirrored/vendored course material that was never migrated, and projects resurrecting legacy Google App Engine guestbook samples, all hit this the moment they are compiled with a modern toolchain.
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/06d0c75787bbe340.
Report an issue: GitHub.