Skip to content

Commit

Permalink
Merge pull request #8538 from Agoric/mhofman/8535-fix-cli-vstorage-no…
Browse files Browse the repository at this point in the history
…t-found

fix(cli): handle not found error in vstorage requests
  • Loading branch information
mergify[bot] authored Nov 17, 2023
2 parents e26232e + 21db80e commit c14f1bb
Show file tree
Hide file tree
Showing 2 changed files with 125 additions and 2 deletions.
112 changes: 112 additions & 0 deletions golang/cosmos/x/vstorage/keeper/querier_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
package keeper

import (
"bytes"
"testing"

agoric "github.com/Agoric/agoric-sdk/golang/cosmos/types"

abci "github.com/tendermint/tendermint/abci/types"

"github.com/cosmos/cosmos-sdk/codec"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
)

func TestQuerier(t *testing.T) {
testKit := makeTestKit()
ctx, keeper := testKit.ctx, testKit.vstorageKeeper
legacyQuerierCdc := codec.NewAminoCodec(codec.NewLegacyAmino())
querier := NewQuerier(keeper, legacyQuerierCdc.LegacyAmino)

// Populate mock data
keeper.SetStorage(ctx, agoric.NewKVEntry("foo.bar", "42"))
keeper.SetStorage(ctx, agoric.NewKVEntry("foo.baz", "hello"))

type testCase struct {
label string
path []string
expected []byte
err *sdkerrors.Error
}
testCases := []testCase{}

// Test invalid endpoint
testCases = append(testCases, []testCase{
{label: "invalid endpoint",
path: []string{"foo"},
err: sdkerrors.ErrUnknownRequest,
},
}...)

// Test invalid arguments to valid data and children endpoints
for _, endpoint := range []string{"data", "children"} {
testCases = append(testCases, []testCase{
{label: endpoint + ": no entry path",
path: []string{endpoint},
err: sdkerrors.ErrInvalidRequest,
},
{label: endpoint + ": too many segments",
path: []string{endpoint, "foo", "bar"},
err: sdkerrors.ErrInvalidRequest,
},
{label: endpoint + ": invalid path",
path: []string{endpoint, ".", ""},
err: sdkerrors.ErrInvalidRequest,
},
}...)
}

// Test data endpoint with valid vstorage path
testCases = append(testCases, []testCase{
{label: "data: non-existent path",
path: []string{"data", "bar"},
// DO NOT CHANGE
// The UI and CLI check for the specific cosmos-sdk error code & codespace
err: sdkerrors.ErrNotFound,
},
{label: "data: path with no data",
path: []string{"data", "foo"},
// DO NOT CHANGE
// The UI and CLI check for the specific cosmos-sdk error code & codespace
err: sdkerrors.ErrNotFound,
},
{label: "data: path with data",
path: []string{"data", "foo.bar"},
expected: []byte("{\n \"value\": \"42\"\n}"),
},
}...)

// Ensure stability of cosmos-sdk error codes
if codespace, code, _ := sdkerrors.ABCIInfo(sdkerrors.ErrNotFound, true); codespace != "sdk" || code != 38 {
t.Errorf("cosmos-sdk ErrNotFound has codespace %s, code %d, expected sdk/38", codespace, code)
}

// Test children endpoint with valid vstorage path
testCases = append(testCases, []testCase{
{label: "children: non-existent path",
path: []string{"children", "bar"},
expected: []byte("{\n \"children\": []\n}"),
},
{label: "children: path with no children",
path: []string{"children", "foo.bar"},
expected: []byte("{\n \"children\": []\n}"),
},
{label: "children: path with children",
path: []string{"children", "foo"},
expected: []byte("{\n \"children\": [\n \"bar\",\n \"baz\"\n ]\n}"),
},
}...)

for _, desc := range testCases {
res, err := querier(ctx, desc.path, abci.RequestQuery{})
if desc.err != nil {
if err == nil {
t.Errorf("%s: got no error, want error %q", desc.label, *desc.err)
} else if codespace, code, _ := sdkerrors.ABCIInfo(err, true); codespace != desc.err.Codespace() || code != desc.err.ABCICode() {
t.Errorf("%s: got error %v, want error %q", desc.label, err, *desc.err)
}
} else if !bytes.Equal(res, desc.expected) {
t.Errorf("%s: wrong result: %#v, expected %#v", desc.label, string(res), string(desc.expected))
}
}
}
15 changes: 13 additions & 2 deletions packages/agoric-cli/src/lib/rpc.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,13 @@ export const makeVStorage = (powers, config = networkConfig) => {
result: { response },
} = data;
if (response?.code !== 0) {
throw Error(
/** @type {any} */
const err = Error(
`error code ${response?.code} reading ${kind} of ${path}: ${response.log}`,
);
err.code = response?.code;
err.codespace = response?.codespace;
throw err;
}
return data;
});
Expand Down Expand Up @@ -143,7 +147,14 @@ export const makeVStorage = (powers, config = networkConfig) => {
));
// console.debug('readAt returned', { blockHeight });
} catch (err) {
if (err.message.match(/unknown request/)) {
if (
// CosmosSDK ErrNotFound; there is no data at the path
(err.codespace === 'sdk' && err.code === 38) ||
// CosmosSDK ErrUnknownRequest; misrepresentation of the same until
// https://github.com/Agoric/agoric-sdk/commit/dafc7c1708977aaa55e245dc09a73859cf1df192
// TODO remove after upgrade-12
err.message.match(/unknown request/)
) {
// console.error(err);
break;
}
Expand Down

0 comments on commit c14f1bb

Please sign in to comment.