调用http.ResponseWriter.Write()时检查错误 [英] Check errors when calling http.ResponseWriter.Write()
问题描述
说我有这个http处理程序:
Say I have this http handler:
func SomeHandler(w http.ResponseWriter, r *http.Request) {
data := GetSomeData()
_, err := w.Write(data)
}
我应该检查 w.Write
返回的错误吗?我看到的示例只是忽略它,什么也不做。另外, http.Error()
之类的函数也不会返回要处理的错误。
Should I check the error returned by w.Write
? Examples I've seen just ignore it and do nothing. Also, functions like http.Error()
do not return an error to be handled.
推荐答案
由您决定。我的建议是,除非某些方法/函数的文档明确指出它永远不会返回非 nil
错误(例如 bytes.Buffer.Write()
),请始终检查错误并最少您可以做的是记录下来,因此,如果发生错误,它将留下一些标记,以便以后出现问题时可以进行调查。
It's up to you. My advice is that unless the documentation of some method / function explicitly states that it never returns a non-nil
error (such as bytes.Buffer.Write()
), always check the error and the least you can do is log it, so if an error occurs, it will leave some mark which you can investigate should it become a problem later.
这对于编写也是如此到 http.ResponseWriter
。
This is also true for writing to http.ResponseWriter
.
您可能会认为 ResponseWriter.Write()
仅在发送数据失败(例如,连接已关闭)时才返回错误。 ,但事实并非如此。实现 http.ResponseWriter
的具体类型是未导出的 http.response
类型,如果您检查未导出的 response.write()
方法,您会看到由于其他一些原因,它可能会返回非 nil
错误。
You might think ResponseWriter.Write()
may only return errors if sending the data fails (e.g. connection closed), but that is not true. The concrete type that implements http.ResponseWriter
is the unexported http.response
type, and if you check the unexported response.write()
method, you'll see it might return a non-nil
error for a bunch of other reasons.
原因 ResponseWriter.Write()
可能返回非 nil的原因
错误:
Reasons why ResponseWriter.Write()
may return a non-nil
error:
- 如果连接被劫持(请参阅
http.Hijacker
):http。 ErrHijacked
- 如果指定了内容长度,并且您尝试编写的内容超出此范围:
http.ErrContentLength
- 如果HTTP方法和/或HTTP状态根本不允许响应正文,并且您尝试写入多个字节:
http.ErrBodyNotAllowed
- 如果将数据写入实际连接失败。
- If the connection was hijacked (see
http.Hijacker
):http.ErrHijacked
- If content length was specified, and you attempt to write more than that:
http.ErrContentLength
- If the HTTP method and / or HTTP status does not allow a response body at all, and you attempt to write more than 0 bytes:
http.ErrBodyNotAllowed
- If writing data to the actual connection fails.
即使你不能对错误进行任何处理,将其记录下来可能对以后调试错误很有帮助。例如。您(或处理程序链中的其他人)劫持了该连接,并稍后尝试写入该连接;您会收到错误消息( http.ErrHijacked
),将其记录下来将立即显示原因。
Even if you can't do anything with the error, logging it may be of great help debugging the error later on. E.g. you (or someone else in the handler chain) hijacked the connection, and you attempt to write to it later; you get an error (http.ErrHijacked
), logging it will reveal the cause immediately.
如果偶尔的错误不能执行任何操作,并且不是 showstopper,则可以创建并使用一个简单的函数来执行检查和日志记录,如下所示:
If you can't do anything with the occasional error and it's not a "showstopper", you may create and use a simple function that does the check and logging, something like this:
func logerr(n int, err error) {
if err != nil {
log.Printf("Write failed: %v", err)
}
}
使用它:
logerr(w.Write(data))
提示自动记录错误
如果您没有即使想一直使用 logerr()
函数,也可以为 http.ResponseWriter
创建一个包装器,此自动:
Tip for "auto-logging" errors
If you don't even want to use the logerr()
function all the time, you may create a wrapper for http.ResponseWriter
which does this "automatically":
type LogWriter struct {
http.ResponseWriter
}
func (w LogWriter) Write(p []byte) (n int, err error) {
n, err = w.ResponseWriter.Write(p)
if err != nil {
log.Printf("Write failed: %v", err)
}
return
}
使用它:
func SomeHandler(w http.ResponseWriter, r *http.Request) {
w = LogWriter{w}
w.Write([]byte("hi"))
}
使用 LogWriter
作为 http.ResponseWriter
的包装,应该写入原始的 http.ResponseWriter
失败,它将被自动记录。
Using LogWriter
as a wrapper around http.ResponseWriter
, should writes to the original http.ResponseWriter
fail, it will be logged automatically.
这也有一个很大的好处,就是不会调用记录器功能,因此您可以传递 LogWriter $的值。 c $ c>拖下链条,所有试图写链的人都将受到监视和记录,他们不必担心,甚至不必知道这一点。
This also has the great benefit of not expecting a logger function to be called, so you can pass a value of your LogWriter
"down" the chain, and everyone who attempts to write to it will be monitored and logged, they don't have to worry or even know about this.
但是在链上传递 LogWriter
时必须小心,因为这还有一个缺点:的值LogWriter
不会实现原始 http.ResponseWriter
可能实现的其他接口,例如 http.Hijacker
或 http.Pusher
。
But care must be taken when passing LogWriter
down the chain, as there's also a downside to this: a value of LogWriter
will not implement other interfaces the original http.ResponseWriter
might also do, e.g. http.Hijacker
or http.Pusher
.
以下是 去游乐场 ,它可以显示此操作,并且还显示 LogWriter
不会实现其他接口;并且还展示了一种方法(使用2个嵌套类型的断言)如何仍然从 LogWriter
( http.Pusher 在示例中为code>。
Here's an example on the Go Playground that shows this in action, and also shows that LogWriter
will not implement other interfaces; and also shows a way (using 2 "nested" type assertions) how to still get out what we want from LogWriter
(an http.Pusher
in the example).
这篇关于调用http.ResponseWriter.Write()时检查错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!