【问题标题】:Filter out broken pipe errors from template execution从模板执行中过滤掉损坏的管道错误
【发布时间】:2015-01-07 07:28:48
【问题描述】:

这类似于 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 应用程序,并且厌倦了在我的其余错误日志中直观地过滤掉损坏的管道错误,但现在我不知道如何过滤掉损坏的管道,而不是使用像字符串这样的脏东西。包含。

【问题讨论】:

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


    【解决方案1】:

    只是要发布最终成为对我有用的包装器的东西。如果有人发现任何问题,请随时插话。

    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
    }
    

    【讨论】:

      【解决方案2】:

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

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

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

      【讨论】:

      • 我包裹了作家,抓住了破管道并忽略了它...感谢您为我指明了正确的方向。
      猜你喜欢
      • 1970-01-01
      • 2016-07-21
      • 2014-04-28
      • 2011-02-12
      • 2015-07-13
      • 1970-01-01
      • 2012-06-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多