Skip to content

Commit

Permalink
Merge pull request #541 from OdyseeTeam/fix-random-endpoint
Browse files Browse the repository at this point in the history
Do not retry input errors
  • Loading branch information
anbsky authored Feb 6, 2025
2 parents 4a631c8 + bc29813 commit bb267ad
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 18 deletions.
38 changes: 26 additions & 12 deletions app/query/caller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -423,18 +423,7 @@ func TestCaller_CallRetryingErrors(t *testing.T) {
okSrv := test.MockHTTPServer(nil)
defer okSrv.Close()

failSrv.QueueResponses(
`{
"jsonrpc": "2.0",
"error": {
"code": -32000,
"message": "sqlite query timed out"
},
"id": 0
}`,
// test.NetworkErrorResponse,
// resolveResponseFree,
)
failSrv.QueueResponses(responseInternalError)
okSrv.QueueResponses(resolveResponseFree)

c := NewCaller(failSrv.URL, 0)
Expand All @@ -452,6 +441,31 @@ func TestCaller_CallRetryingErrors(t *testing.T) {
require.NotEmpty(t, rpcResponse.Result.(map[string]any)["what"])
}

func TestCaller_CallNotRetryingInputErrors(t *testing.T) {
var err error
failSrv := test.MockHTTPServer(nil)
defer failSrv.Close()
okSrv := test.MockHTTPServer(nil)
defer okSrv.Close()

failSrv.QueueResponses(responseUserInputError)
okSrv.QueueResponses(resolveResponseFree)

c := NewCaller(failSrv.URL, 0)
c.AddBackupEndpoints([]string{okSrv.URL})

cache, _, _, teardown := sturdycache.CreateTestCache(t)
defer teardown()
c.Cache = NewQueryCache(cache)
require.NoError(t, err)

rpcReq := jsonrpc.NewRequest(MethodResolve, map[string]any{"urls": "what"})
rpcResponse, err := c.Call(bgctx(), rpcReq)
require.NoError(t, err)
require.NotNil(t, rpcResponse.Error)
require.Equal(t, "expected string or bytes-like object", rpcResponse.Error.Message)
}

func TestCaller_CallSDKError(t *testing.T) {
srv := test.MockHTTPServer(nil)
defer srv.Close()
Expand Down
22 changes: 22 additions & 0 deletions app/query/errors.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package query

import (
"strings"

"github.com/ybbus/jsonrpc/v2"
)

var userInputSDKErrors = []string{
"expected string or bytes-like object",
}

// isUserInputError checks if error is of the kind where retrying a request with the same input will result in the same error.
func isUserInputError(resp *jsonrpc.RPCResponse) bool {
for _, m := range userInputSDKErrors {
if strings.Contains(resp.Error.Message, m) {
return true
}

}
return false
}
5 changes: 3 additions & 2 deletions app/query/metrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,9 @@ const (
CacheAreaChainquery = "chainquery"
CacheAreaInvalidateCall = "invalidate_call"

CacheRetrievalErrorNet = "net"
CacheRetrievalErrorSdk = "sdk"
CacheRetrieverErrorNet = "net"
CacheRetrieverErrorSdk = "sdk"
CacheRetrieverErrorInput = "input"
)

var (
Expand Down
11 changes: 7 additions & 4 deletions app/query/processors.go
Original file line number Diff line number Diff line change
Expand Up @@ -663,23 +663,26 @@ func preflightCacheHook(caller *Caller, ctx context.Context) (*jsonrpc.RPCRespon
switch {
case err == nil && resp.Error == nil:
if attempt > 0 {
QueryCacheRetrySuccesses.Observe(float64(attempt))
log.Infof(
"cache retriever %s attempt #%d succeeded (after spending %.2f seconds) for %d @ %s",
query.Method(), attempt, time.Since(totalStart).Seconds(), caller.userID, caller.Endpoint(),
)
QueryCacheRetrySuccesses.Observe(float64(attempt))
}
return resp, err
case err != nil:
QueryCacheRetrievalFailures.WithLabelValues(CacheRetrievalErrorNet, query.Method()).Inc()
QueryCacheRetrievalFailures.WithLabelValues(CacheRetrieverErrorNet, query.Method()).Inc()
log.Infof(
"cache retriever %s attempt #%d failed after %.3fs, err=%+v for %d @ %s",
query.Method(), attempt, duration, err, caller.userID, caller.Endpoint(),
)
case resp.Error != nil && isUserInputError(resp):
QueryCacheRetrievalFailures.WithLabelValues(CacheRetrieverErrorInput, query.Method()).Inc()
return resp, err
case resp.Error != nil:
QueryCacheRetrievalFailures.WithLabelValues(CacheRetrievalErrorSdk, query.Method()).Inc()
QueryCacheRetrievalFailures.WithLabelValues(CacheRetrieverErrorSdk, query.Method()).Inc()
log.Infof(
"cache retriever %s attempt #%d failed after %.3fs, resp=%+v @ %d @ %s",
"cache retriever %s attempt #%d failed after %.3fs, resp=%+v for %d @ %s",
query.Method(), attempt, duration, resp.Error, caller.userID, caller.Endpoint(),
)
}
Expand Down
18 changes: 18 additions & 0 deletions app/query/response_strings_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -478,3 +478,21 @@ var resolveResponseCouldntFind = `
"id": 0
}
`

var responseInternalError = `{
"jsonrpc": "2.0",
"error": {
"code": -32000,
"message": "sqlite query timed out"
},
"id": 0
}`

var responseUserInputError = `{
"jsonrpc": "2.0",
"error": {
"code": -32500,
"message": "expected string or bytes-like object"
},
"id": 0
}`

0 comments on commit bb267ad

Please sign in to comment.