3

这类似于过滤掉损坏的管道错误,但有一些复杂性 - 当用户在执行模板(html/template.Execute 或 text/template.Execute)时按下浏览器上的“停止”按钮时,会发生损坏的管道错误.

但是,我相信 text/template 包返回的错误只是 *errors.errorString 类型,因为损坏的管道消息似乎包含在其他一些信息文本中,因此无法对 net.OpErr 进行类型断言以进行比较目的。

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

write tcp 127.0.0.1:60739: 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 应用程序,并且厌倦了在我的其余错误日志中直观地过滤掉损坏的管道错误,但是现在我不知道如何过滤掉损坏的管道,而不是使用像 strings.Contains 这样的脏东西。

4

2 回答 2

3

只是要发布最终成为对我有用的包装器。如果有人看到有什么不妥,请随时插话。

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 "stop") errors
        if nErr, ok := err.(*net.OpError); ok {
            if nErr.Err == syscall.EPIPE {
                return n, nil
            }
        }
    }
    return n, err
}
于 2014-11-11T14:03:07.623 回答
2

这是一个日志记录问题。我宁愿在我的日志中包含更多信息并且必须对其进行过滤,而不是在此错误消息是问题的唯一痕迹时尝试追踪错误。

正如您所提到的,错误是通过创建的errors.New。您所拥有的只是一个字符串,因此从执行模板中过滤此错误的唯一方法是检查所述字符串,可能使用strings.Contains.

处理此问题的另一种方法是将您包装起来io.Writer以捕获broken pipe,然后默默地丢弃任何后续写入。

于 2014-11-10T22:16:30.340 回答