retry on "connection reset by peer" (#3138)
retry when we receive a "connection reset by peer" error --- #### Does this PR need a docs update or release note? - [x] ✅ Yes, it's included #### Type of change - [x] 🐛 Bugfix #### Issue(s) * #3129 #### Test Plan - [x] 💪 Manual - [x] ⚡ Unit test
This commit is contained in:
parent
5166e61115
commit
09ef350bc0
@ -23,6 +23,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
- Skip OneNote items bigger than 2GB (Graph API prevents us from downloading them)
|
||||
- ParentPath of json output for Exchange calendar now shows names instead of IDs.
|
||||
- Fixed failure when downloading huge amount of attachments
|
||||
- Graph API requests that return an ECONNRESET error are now retried.
|
||||
|
||||
### Known Issues
|
||||
- Restoring a OneDrive or SharePoint file with the same name as a file with that name as its M365 ID may restore both items.
|
||||
|
||||
@ -8,6 +8,7 @@ import (
|
||||
"net/url"
|
||||
"os"
|
||||
"strings"
|
||||
"syscall"
|
||||
|
||||
"github.com/alcionai/clues"
|
||||
"github.com/microsoftgraph/msgraph-sdk-go/models"
|
||||
@ -116,6 +117,10 @@ func IsErrTimeout(err error) bool {
|
||||
os.IsTimeout(err)
|
||||
}
|
||||
|
||||
func IsErrConnectionReset(err error) bool {
|
||||
return errors.Is(err, syscall.ECONNRESET)
|
||||
}
|
||||
|
||||
func IsErrUnauthorized(err error) bool {
|
||||
// TODO: refine this investigation. We don't currently know if
|
||||
// a specific item download url expired, or if the full connection
|
||||
|
||||
@ -3,6 +3,7 @@ package graph
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"syscall"
|
||||
"testing"
|
||||
|
||||
"github.com/alcionai/clues"
|
||||
@ -32,6 +33,35 @@ func odErr(code string) *odataerrors.ODataError {
|
||||
return odErr
|
||||
}
|
||||
|
||||
func (suite *GraphErrorsUnitSuite) TestIsErrConnectionReset() {
|
||||
table := []struct {
|
||||
name string
|
||||
err error
|
||||
expect assert.BoolAssertionFunc
|
||||
}{
|
||||
{
|
||||
name: "nil",
|
||||
err: nil,
|
||||
expect: assert.False,
|
||||
},
|
||||
{
|
||||
name: "non-matching",
|
||||
err: assert.AnError,
|
||||
expect: assert.False,
|
||||
},
|
||||
{
|
||||
name: "matching",
|
||||
err: syscall.ECONNRESET,
|
||||
expect: assert.True,
|
||||
},
|
||||
}
|
||||
for _, test := range table {
|
||||
suite.Run(test.name, func() {
|
||||
test.expect(suite.T(), IsErrConnectionReset(test.err))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (suite *GraphErrorsUnitSuite) TestIsErrDeletedInFlight() {
|
||||
table := []struct {
|
||||
name string
|
||||
|
||||
@ -213,7 +213,7 @@ func (middleware RetryHandler) retryRequest(
|
||||
}
|
||||
|
||||
response, err := pipeline.Next(req, middlewareIndex)
|
||||
if err != nil && !IsErrTimeout(err) {
|
||||
if err != nil && !IsErrTimeout(err) && !IsErrConnectionReset(err) {
|
||||
return response, Stack(ctx, err).With("retry_count", executionCount)
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user