11

假设我有html/template以下内容:

<html>
<body>
    <p>{{SomeFunc .SomeData}}</p>
</body>

有时会SomeFunc返回错误。有没有一种惯用的方法来处理这个问题?

如果我直接写入ResponseWriter,则在遇到错误之前已经写入了状态代码 200。

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?
}

最好我会返回一个状态码 400 或类似的,但如果我template.Execute直接在ResponseWriter. 有什么我想念的吗?

4

1 回答 1

11

由于模板引擎即时生成输出,因此SomeFunc调用之前的部分模板已经发送到输出。如果输出没有缓冲,它们(连同 HTTP 200 状态)可能已经被发送。

你对此无能为力。

您可以做的是在致电之前进行检查template.Execute()SomeFunc()在普通情况下,调用并检查其返回值就足够了。如果你选择这个路径并且返回值SomeFunc()很复杂,你不必从模板中再次调用它,你可以简单地将它的返回值传递给你传递给模板的参数并在模板中引用这个值(所以SomeFunc()不必执行两次)。

如果这还不够或您无法控制它,您可以创建一个bytes.Buffer,执行您的模板,将其定向到此缓冲区,并在Execute()返回后检查是否有错误。如果有错误,请发回正确的错误消息/页面。如果一切顺利,您可以将缓冲区的内容发送到ResponseWriter.

这可能看起来像这样:

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)
}
于 2015-06-13T19:04:38.387 回答