Idiomatic way to handle template errors in golang

时间秒杀一切 提交于 2019-12-06 23:04:40

问题


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?


回答1:


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 call SomeFunc() and check its return value. If you choose this path and the return value of SomeFunc() 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 (so SomeFunc() won't have to be executed twice).

If this is not enough or you can't control it, you can create a bytes.Buffer, execute your template directed into this buffer, and after the Execute() 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 the ResponseWriter.

This could look something like this:

buf := &bytes.Buffer{}
err := tmpl.Execute(buf, data)
if err != nil {
    // Send back error message, for example:
    http.Error(w, "Hey, Request was bad!", http.StatusBadRequest) // HTTP 400 status
} else {
    // No error, send the content, HTTP 200 response status implied
    buf.WriteTo(w)
}


来源:https://stackoverflow.com/questions/30821745/idiomatic-way-to-handle-template-errors-in-golang

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!