Io 从模板执行中筛选出断开的管道错误

Io 从模板执行中筛选出断开的管道错误,io,go,system-calls,broken-pipe,epipe,Io,Go,System Calls,Broken Pipe,Epipe,这与类似,但有点复杂-当用户在执行模板(html/template.Execute或text/template.Execute)时按下浏览器上的“停止”按钮时,会发生断管错误 但是,我认为text/template包返回的错误只是类型为*errors.errorString,因为断管消息似乎被包装在其他一些信息性文本中,因此无法对net.oper进行类型断言以进行比较 例如,典型的断开管道错误字符串如下所示 写入tcp 127.0.0.1:60739:断管 正在执行的模板返回的管道错误字符串如下

这与类似,但有点复杂-当用户在执行模板(html/template.Execute或text/template.Execute)时按下浏览器上的“停止”按钮时,会发生断管错误

但是,我认为text/template包返回的错误只是类型为*errors.errorString,因为断管消息似乎被包装在其他一些信息性文本中,因此无法对net.oper进行类型断言以进行比较

例如,典型的断开管道错误字符串如下所示

写入tcp 127.0.0.1:60739:断管

正在执行的模板返回的管道错误字符串如下所示:


template:header.html:1:0:在执行“header.html”这是一个日志问题。我宁愿在我的日志中有更多的信息,并且必须对其进行过滤,也不愿在这个错误消息是问题的唯一线索时尝试跟踪错误

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


另一种处理方法是将你的
io.Writer
包装起来,抓住
破裂的管道
,然后默默地扔掉任何后续的写入操作。

只想发布最终对我有效的包装器。如果有人发现什么不对劲,请随时插话

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
}

我把作家裹起来,抓住那根断了的烟斗,不理它。。。谢谢你给我指明了正确的方向。