Say I have a html/template
like the following:
<html>
<body>
<p>{{SomeFunc .SomeData}}</p>
</body>
and sometimes SomeFunc
returns an error. Is there an idiomatic way to deal with this?
If I write directly to the ResponseWriter
, then a status code 200 has already been written before I encounter the error.
var tmpl *template.Template
func Handler(w http.ResponseWriter, r *http.Request) {
err := tmpl.Execute(w, data)
// "<html><body><p>" has already been written...
// what to do with err?
}
Preferably I would return a status code 400 or some such, but I can't see a way to do this if I use template.Execute
directly on the ResponseWriter
. Is there something I'm missing?
Since the template engine generates the output on-the-fly, parts of the template preceding the
SomeFunc
call are already sent to the output. And if the output is not buffered, they (along with the HTTP 200 status) may already be sent.You can't do anything about that.
What you can do is perform the check before you call
template.Execute()
. In trivial case it should be enough to callSomeFunc()
and check its return value. If you choose this path and the return value ofSomeFunc()
is complex, you do not have to call it again from the template, you can simply pass its return value to the params you pass to the template and refer to this value in the template (soSomeFunc()
won't have to be executed twice).If this is not enough or you can't control it, you can create a
bytes.Buffer
orstrings.Builder
, execute your template directed into this buffer, and after theExecute()
returns, check if there were errors. If there were errors, send back a proper error message / page. If everything went ok, you can just send the content of the buffer to theResponseWriter
.This could look something like this: