从模板执行中过滤掉损坏的管道错误

时间:2014-11-10 21:21:40

标签: io go system-calls broken-pipe epipe

这类似于Filter out broken pipe errors,但是有并发症 - 当用户在执行模板时按下浏览器上的“停止”按钮(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应用程序,我厌倦了在其余的错误日志中直观地过滤掉管道错误但是现在我不知道如何过滤掉破坏的管道,除了使用像字符串一样脏的东西。包含。

2 个答案:

答案 0 :(得分:2)

只是发布最终成为适合我的包装器。如果有人发现任何错误,请随意加入。

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
}

答案 1 :(得分:1)

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

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

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