github.com/stevenmatthewt/agent@v3.5.4+incompatible/api/retryable.go (about)

     1  package api
     2  
     3  import (
     4  	"io"
     5  	"net"
     6  	"net/url"
     7  	"strings"
     8  	"syscall"
     9  )
    10  
    11  var retrableErrorSuffixes = []string{
    12  	syscall.ECONNREFUSED.Error(),
    13  	syscall.ECONNRESET.Error(),
    14  	syscall.ETIMEDOUT.Error(),
    15  	"no such host",
    16  	"remote error: handshake failure",
    17  	io.ErrUnexpectedEOF.Error(),
    18  	io.EOF.Error(),
    19  }
    20  
    21  // Looks at a bunch of connection related errors, and returns true if the error
    22  // matches one of them.
    23  func IsRetryableError(err error) bool {
    24  	if neterr, ok := err.(net.Error); ok {
    25  		if neterr.Temporary() {
    26  			return true
    27  		}
    28  	}
    29  
    30  	if neterr, ok := err.(net.Error); ok && neterr.Timeout() {
    31  		return true
    32  	}
    33  
    34  	if urlerr, ok := err.(*url.Error); ok {
    35  		if strings.Contains(urlerr.Error(), "use of closed network connection") {
    36  			return true
    37  		}
    38  
    39  		if neturlerr, ok := urlerr.Err.(net.Error); ok && neturlerr.Timeout() {
    40  			return true
    41  		}
    42  	}
    43  
    44  	if strings.Contains(err.Error(), "request canceled while waiting for connection") {
    45  		return true
    46  	}
    47  
    48  	s := err.Error()
    49  	for _, suffix := range retrableErrorSuffixes {
    50  		if strings.HasSuffix(s, suffix) {
    51  			return true
    52  		}
    53  	}
    54  
    55  	return false
    56  }