英文:
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 "header.html" at <div id="header...>: 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 "stop") 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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论