过滤掉模板执行中的断开管道错误。

huangapple go评论81阅读模式
英文:

Filter out broken pipe errors from template execution

问题

这类似于https://stackoverflow.com/questions/11003692/filter-out-broken-pipe-errors,但有一些复杂性 - 当用户在执行模板(html/template.Execute或text/template.Execute)时按下浏览器上的“停止”按钮时,会出现一个broken pipe错误。

然而,我认为text/template包返回的错误只是*errors.errorString类型,因为broken pipe消息似乎被包装在其他一些信息性文本中,所以无法进行类型断言以进行比较。

例如,一个典型的broken pipe错误字符串看起来像

write tcp 127.0.0.1:60739: broken pipe

执行模板时返回的broken pipe错误字符串看起来像:

template: header.html:1:0: executing "header.html" at <div id="header...>: write tcp 127.0.0.1:60739: broken pipe

我有一个用Go编写的生产级Web应用程序,我厌倦了在我的错误日志中目测过滤掉broken pipe错误,但现在我不知道如何过滤掉broken pipe,除非使用一些不太好的方法,比如strings.Contains。

英文:

This is similar to https://stackoverflow.com/questions/11003692/filter-out-broken-pipe-errors , but with complications - when a user presses the "stop" button on their browser while a template is executing (html/template.Execute or text/template.Execute), a broken pipe error occurs.

However, I believe that the error returned by the text/template package is simply of type *errors.errorString as the broken pipe message appears to be wrapped in some other informational text and so no type assertion can be made to net.OpErr for comparison purposes.

For example, a typical broken pipe error string would look like

write tcp 127.0.0.1:60739: broken pipe

A broken pipe error string returned by an executing template looks like:

template: header.html:1:0: executing &quot;header.html&quot; at &lt;div id=&quot;header...&gt;: write tcp 127.0.0.1:60739: broken pipe

I have a production web application written in Go and am sick of visually filtering out broken pipe errors in the rest of my error logs but right now I have no clue how to filter out broken pipe other than using something dirty like strings.Contains.

答案1

得分: 3

以下是我为您翻译的内容:

只是要发布最终对我有效的包装器。如果有人发现有什么问题,请随时提出。

type templateWriter struct {
    writer io.Writer
}

func (w templateWriter) Write(p []byte) (int, error) {
    n, err := w.writer.Write(p)
    if err != nil {
        // 过滤掉断开的管道(用户按下“停止”)错误
        if nErr, ok := err.(*net.OpError); ok {
            if nErr.Err == syscall.EPIPE {
                return n, nil
            }
        }
    }
    return n, err
}

希望对您有所帮助!

英文:

Just going to post what ended up being the wrapper that worked for me. If anyone sees anything wrong, feel free to chime in.

type templateWriter struct {
    writer io.Writer
}

func (w templateWriter) Write(p []byte) (int, error) {
    n, err := w.writer.Write(p)
	if err != nil {
    	// Filter out broken pipe (user pressed &quot;stop&quot;) errors
    	if nErr, ok := err.(*net.OpError); ok {
	    	if nErr.Err == syscall.EPIPE {
				return n, nil
			}
		}
	}
	return n, err
}

答案2

得分: 2

这是一个日志记录问题。我宁愿在日志中获得更多信息并进行过滤,也不愿在出现错误消息时追踪错误。

正如你提到的,错误是通过errors.New创建的。你只有一个字符串,所以过滤执行模板时唯一的方法就是检查该字符串,可能要使用strings.Contains

另一种处理方法是包装你的io.Writer以捕获"broken pipe"错误,然后静默丢弃任何后续的写入操作。

英文:

This is a logging issue. I'd rather have more information in my logs and have to filter it, than try and track down a bug when this error message is the only trace of the problem.

As you mentioned, the error is created via errors.New. All you have is a string, so the only way to filter this error from executing the template is going to be by inspecting said string, probably with strings.Contains.

Another way to handle this would be to wrap your io.Writer to catch the broken pipe, then silently throw away any subsequent writes.

huangapple
  • 本文由 发表于 2014年11月11日 05:21:39
  • 转载请务必保留本文链接:https://go.coder-hub.com/26853200.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定