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)
|
- 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.
|
- ParentPath of json output for Exchange calendar now shows names instead of IDs.
|
||||||
- Fixed failure when downloading huge amount of attachments
|
- Fixed failure when downloading huge amount of attachments
|
||||||
|
- Graph API requests that return an ECONNRESET error are now retried.
|
||||||
|
|
||||||
### Known Issues
|
### 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.
|
- 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"
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
"syscall"
|
||||||
|
|
||||||
"github.com/alcionai/clues"
|
"github.com/alcionai/clues"
|
||||||
"github.com/microsoftgraph/msgraph-sdk-go/models"
|
"github.com/microsoftgraph/msgraph-sdk-go/models"
|
||||||
@ -116,6 +117,10 @@ func IsErrTimeout(err error) bool {
|
|||||||
os.IsTimeout(err)
|
os.IsTimeout(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func IsErrConnectionReset(err error) bool {
|
||||||
|
return errors.Is(err, syscall.ECONNRESET)
|
||||||
|
}
|
||||||
|
|
||||||
func IsErrUnauthorized(err error) bool {
|
func IsErrUnauthorized(err error) bool {
|
||||||
// TODO: refine this investigation. We don't currently know if
|
// TODO: refine this investigation. We don't currently know if
|
||||||
// a specific item download url expired, or if the full connection
|
// a specific item download url expired, or if the full connection
|
||||||
|
|||||||
@ -3,6 +3,7 @@ package graph
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"syscall"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/alcionai/clues"
|
"github.com/alcionai/clues"
|
||||||
@ -32,6 +33,35 @@ func odErr(code string) *odataerrors.ODataError {
|
|||||||
return odErr
|
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() {
|
func (suite *GraphErrorsUnitSuite) TestIsErrDeletedInFlight() {
|
||||||
table := []struct {
|
table := []struct {
|
||||||
name string
|
name string
|
||||||
|
|||||||
@ -213,7 +213,7 @@ func (middleware RetryHandler) retryRequest(
|
|||||||
}
|
}
|
||||||
|
|
||||||
response, err := pipeline.Next(req, middlewareIndex)
|
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)
|
return response, Stack(ctx, err).With("retry_count", executionCount)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user