Skip to content

x/website/_content/doc/articles/wiki: "Writing Web Applications" example writes the reponse header twice #27789

Open
@Houndie

Description

@Houndie

What version of Go are you using (go version)?

go1.11

Does this issue reproduce with the latest release?

Yes

What operating system and processor architecture are you using (go env)?


GOARCH="amd64"
GOBIN="/home/jabenze/go/bin"
GOCACHE="/home/jabenze/.cache/go-build"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/home/jabenze/go"
GOPROXY=""
GORACE=""
GOROOT="/usr/lib/go"
GOTMPDIR=""
GOTOOLDIR="/usr/lib/go/pkg/tool/linux_amd64"
GCCGO="gccgo"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD=""
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build876174949=/tmp/go-build -gno-record-gcc-switches"

What did you do?

Follow the "Writing Web Applications" tutorial here, up through the error handling section here: https://golang.org/doc/articles/wiki/#tmp_9. L

Look at the function renderTemplate, reproduced here:

func renderTemplate(w http.ResponseWriter, tmpl string, p *Page) {
    t, err := template.ParseFiles(tmpl + ".html")
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }
    err = t.Execute(w, p)
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
    }
}

Modify the Page data structure by removing a field (or modify the template to reference a nonexisting field) so that the line: err = t.Execute(w, p) will cause an error to be created. Observe the response code sent by the application. The following line: http.Error(w, err.Error(), http.StatusInternalServerError) would imply the response code to be 500, however, the application returns 200.

This is because t.Execute is calling w.Write which, because w.WriteHeader has not yet been called, causes an implicit call to w.WriteHeader(200). Further calls to w.WriteHeader, such as the one inside http.Error are ignored.

There is no way to able to send a 500 error code in the case of all errors, since w.Write itself can return an error, and at some point, one has to simply log an error and return without setting an error code. Optionally, the example could render to a bytes.Buffer so that template rendering errors could be caught.

What did you expect to see?

Based on the code, a 500 error code

What did you see instead?

Error code 200.

Metadata

Metadata

Assignees

No one assigned

    Labels

    DocumentationIssues describing a change to documentation.NeedsFixThe path to resolution is known, but the work has not been done.website

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions