diff --git a/trie/node.go b/trie/node.go index fd229363a24..e75c29d2ff3 100644 --- a/trie/node.go +++ b/trie/node.go @@ -121,18 +121,26 @@ func computeAndSetNodeHash(n node) ([]byte, error) { func getNodeFromDBAndDecode(n []byte, db common.DBWriteCacher, marshalizer marshal.Marshalizer, hasher hashing.Hasher) (node, error) { encChild, err := db.Get(n) if err != nil { - logLevel := logger.LogWarning - if errors.IsClosingError(err) { - logLevel = logger.LogTrace - } + treatLogError(log, err, n) - log.Log(logLevel, common.GetNodeFromDBErrorString, "error", err, "key", n, "stack trace", string(debug.Stack())) return nil, fmt.Errorf(common.GetNodeFromDBErrorString+" %w for key %v", err, hex.EncodeToString(n)) } return decodeNode(encChild, marshalizer, hasher) } +func treatLogError(logInstance logger.Logger, err error, key []byte) { + logLevel := logger.LogTrace + extraInfo := make([]interface{}, 0, 6) + extraInfo = append(extraInfo, "error", err, "key", key) + if !errors.IsClosingError(err) { + logLevel = logger.LogWarning + extraInfo = append(extraInfo, "stack trace", string(debug.Stack())) + } + + logInstance.Log(logLevel, common.GetNodeFromDBErrorString, extraInfo...) +} + func resolveIfCollapsed(n node, pos byte, db common.DBWriteCacher) error { err := n.isEmptyOrNil() if err != nil { diff --git a/trie/node_test.go b/trie/node_test.go index dbc30aa4174..3eb3e9ffb51 100644 --- a/trie/node_test.go +++ b/trie/node_test.go @@ -2,6 +2,7 @@ package trie import ( "context" + "errors" "testing" "time" @@ -9,9 +10,13 @@ import ( "github.com/multiversx/mx-chain-core-go/core/atomic" "github.com/multiversx/mx-chain-go/common" dataMock "github.com/multiversx/mx-chain-go/dataRetriever/mock" + mxErrors "github.com/multiversx/mx-chain-go/errors" + "github.com/multiversx/mx-chain-go/storage" "github.com/multiversx/mx-chain-go/testscommon" "github.com/multiversx/mx-chain-go/trie/keyBuilder" + logger "github.com/multiversx/mx-chain-logger-go" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestNode_hashChildrenAndNodeBranchNode(t *testing.T) { @@ -623,6 +628,63 @@ func TestShouldStopIfContextDoneBlockingIfBusy(t *testing.T) { }) } +func TestTreatLogError(t *testing.T) { + t.Parallel() + + t.Run("error is not of type of closing error", func(t *testing.T) { + t.Parallel() + + key := []byte("key") + err := errors.New("trie was not found") + wasCalled := false + logInstance := &testscommon.LoggerStub{ + LogCalled: func(logLevel logger.LogLevel, message string, args ...interface{}) { + wasCalled = true + require.Equal(t, logger.LogWarning, logLevel) + require.Equal(t, common.GetNodeFromDBErrorString, message) + require.Equal(t, 6, len(args)) + expectedFirst5Args := []interface{}{"error", err, "key", key, "stack trace"} + require.Equal(t, expectedFirst5Args, args[:5]) + }, + } + + treatLogError(logInstance, err, key) + assert.True(t, wasCalled) + treatLogError(log, err, key) //display only + }) + t.Run("error is of type of closing error", func(t *testing.T) { + t.Parallel() + + key := []byte("key") + numCalled := 0 + var err error + + logInstance := &testscommon.LoggerStub{ + LogCalled: func(logLevel logger.LogLevel, message string, args ...interface{}) { + numCalled++ + require.Equal(t, logger.LogTrace, logLevel) + require.Equal(t, common.GetNodeFromDBErrorString, message) + require.Equal(t, 4, len(args)) + expectedFirst5Args := []interface{}{"error", err, "key", key} + require.Equal(t, expectedFirst5Args, args) + }, + } + + t.Run("db is closed", func(t *testing.T) { + crtCounter := numCalled + err = storage.ErrDBIsClosed + treatLogError(logInstance, err, key) + assert.Equal(t, crtCounter+1, numCalled) + }) + t.Run("context closing", func(t *testing.T) { + crtCounter := numCalled + err = mxErrors.ErrContextClosing + treatLogError(logInstance, err, key) + assert.Equal(t, crtCounter+1, numCalled) + }) + }) +} + func Benchmark_ShouldStopIfContextDoneBlockingIfBusy(b *testing.B) { ctx := context.Background() b.ResetTimer()