// Chapter 34 example: what happens when Execute fails halfway. The template asks // for a field that does not exist, so that Execute always fails here. // Run with: go run exercises/34/02-execute-error.go package main import ( "bytes" "fmt" "html/template" "net/http" ) type pageData struct { Name string } const brokenText = `
{{.Missing}}
` var brokenTemplate = template.Must(template.New("broken").Parse(brokenText)) // handleDirect writes straight to the visitor, so the first half of the page // has gone out by the time Execute fails. func handleDirect(w http.ResponseWriter, r *http.Request) { data := pageData{Name: "Keiko"} w.Header().Set("Content-Type", "text/html; charset=utf-8") err := brokenTemplate.Execute(w, data) if err != nil { fmt.Println("Template error:", err) } } // handleBuffered builds the whole page in memory first, so nothing has gone out // when Execute fails, and it can still choose the status. func handleBuffered(w http.ResponseWriter, r *http.Request) { data := pageData{Name: "Keiko"} var page bytes.Buffer err := brokenTemplate.Execute(&page, data) if err != nil { fmt.Println("Template error:", err) http.Error(w, "The page could not be built.", http.StatusInternalServerError) return } w.Header().Set("Content-Type", "text/html; charset=utf-8") page.WriteTo(w) } func main() { http.HandleFunc("GET /direct", handleDirect) http.HandleFunc("GET /buffered", handleBuffered) fmt.Println("Server running at http://localhost:8080") fmt.Println("Press Ctrl+C to stop it.") err := http.ListenAndServe("localhost:8080", nil) if err != nil { fmt.Println("Server stopped:", err) } }