调用http.ResponseWriter.Write()时检查错误 [英] Check errors when calling http.ResponseWriter.Write()

查看:130
本文介绍了调用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 拖下链条,所有试图写链的人都将受到监视和记录,他们不必担心,甚至不必知道这一点。

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

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屋!

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