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