Filter out broken pipe errors from template execut

2019-05-26 15:46发布

This is similar to 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.

2条回答
萌系小妹纸
2楼-- · 2019-05-26 16:17

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
}
查看更多
Root(大扎)
3楼-- · 2019-05-26 16:30

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.

查看更多
登录 后发表回答