在Golang中处理模板错误的惯用方式 [英] Idiomatic way to handle template errors in golang

查看:54
本文介绍了在Golang中处理模板错误的惯用方式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

说我有一个 html/template ,如下所示:

Say I have a html/template like the following:

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

,有时 SomeFunc 返回错误.有没有惯用的方法来解决这个问题?

and sometimes SomeFunc returns an error. Is there an idiomatic way to deal with this?

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

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

最好返回状态码400或类似的状态码,但是如果我直接在 ResponseWriter 上使用 template.Execute ,则看不到做到这一点的方法..有什么我想念的吗?

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?

推荐答案

由于模板引擎会即时生成输出,因此 SomeFunc 调用之前的模板部分已经发送到了输出.并且,如果未缓冲输出,则可能已经发送了它们(以及HTTP 200状态).

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.

您对此无能为力.

您可以做的是在调用 template.Execute之前执行检查.() .在平凡的情况下,只需调用 SomeFunc()并检查其返回值就足够了.如果选择此路径,并且 SomeFunc()的返回值很复杂,则不必从模板中再次调用它,只需将其返回值传递给传递给模板的参数即可并在模板中引用该值(因此 SomeFunc()不必执行两次).

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).

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

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.

这可能看起来像这样:

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

这篇关于在Golang中处理模板错误的惯用方式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆