Skip to content

Commit

Permalink
fix: grpc-gateway error codes (#9015)
Browse files Browse the repository at this point in the history
* update grpc query handler

* try fix http response error codes

* add test

* add changelog

Co-authored-by: Alessio Treglia <alessio@tendermint.com>
Co-authored-by: Amaury <1293565+amaurym@users.noreply.github.com>
  • Loading branch information
3 people authored Mar 29, 2021
1 parent 37a8c7b commit 636e659
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 3 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ Ref: https://keepachangelog.com/en/1.0.0/

### Bug Fixes

* (gRPC) [\#9015](https://github.com/cosmos/cosmos-sdk/pull/9015) Fix invalid status code when accessing gRPC endpoints.
* (gRPC) [\#8945](https://github.com/cosmos/cosmos-sdk/pull/8945) gRPC reflection now works correctly.
* (keyring) [#\8635](https://github.com/cosmos/cosmos-sdk/issues/8635) Remove hardcoded default passphrase value on `NewMnemonic`
* (x/bank) [\#8434](https://github.com/cosmos/cosmos-sdk/pull/8434) Fix legacy REST API `GET /bank/total` and `GET /bank/total/{denom}` in swagger
Expand Down
18 changes: 17 additions & 1 deletion client/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,16 @@ import (
"strings"

"github.com/pkg/errors"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"

abci "github.com/tendermint/tendermint/abci/types"
tmbytes "github.com/tendermint/tendermint/libs/bytes"
rpcclient "github.com/tendermint/tendermint/rpc/client"

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

// GetNode returns an RPC client. If the context's client is not defined, an
Expand Down Expand Up @@ -84,7 +87,7 @@ func (ctx Context) queryABCI(req abci.RequestQuery) (abci.ResponseQuery, error)
}

if !result.Response.IsOK() {
return abci.ResponseQuery{}, errors.New(result.Response.Log)
return abci.ResponseQuery{}, sdkErrorToGRPCError(result.Response)
}

// data from trusted node or subspace query doesn't need verification
Expand All @@ -95,6 +98,19 @@ func (ctx Context) queryABCI(req abci.RequestQuery) (abci.ResponseQuery, error)
return result.Response, nil
}

func sdkErrorToGRPCError(resp abci.ResponseQuery) error {
switch resp.Code {
case sdkerrors.ErrInvalidRequest.ABCICode():
return status.Error(codes.InvalidArgument, resp.Log)
case sdkerrors.ErrUnauthorized.ABCICode():
return status.Error(codes.Unauthenticated, resp.Log)
case sdkerrors.ErrKeyNotFound.ABCICode():
return status.Error(codes.NotFound, resp.Log)
default:
return status.Error(codes.Unknown, resp.Log)
}
}

// query performs a query to a Tendermint node with the provided store name
// and path. It returns the result and height of the query upon success
// or an error if the query fails.
Expand Down
36 changes: 34 additions & 2 deletions x/staking/client/rest/grpc_query_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,16 @@ package rest_test

import (
"fmt"
"io/ioutil"
"net/http"
"testing"

"github.com/cosmos/cosmos-sdk/client/flags"

"github.com/gogo/protobuf/proto"
"github.com/stretchr/testify/suite"

"github.com/cosmos/cosmos-sdk/client/flags"
"github.com/cosmos/cosmos-sdk/crypto/hd"
"github.com/cosmos/cosmos-sdk/crypto/keyring"
"github.com/cosmos/cosmos-sdk/testutil"
"github.com/cosmos/cosmos-sdk/testutil/network"
sdk "github.com/cosmos/cosmos-sdk/types"
Expand Down Expand Up @@ -411,6 +414,35 @@ func (s *IntegrationTestSuite) TestQueryUnbondingDelegationGRPC() {
}
}

func (s *IntegrationTestSuite) TestQueryDelegationsResponseCode() {
val := s.network.Validators[0]

// Create new account in the keyring.
info, _, err := val.ClientCtx.Keyring.NewMnemonic("test", keyring.English, sdk.FullFundraiserPath, keyring.DefaultBIP39Passphrase, hd.Secp256k1)
s.Require().NoError(err)
newAddr := sdk.AccAddress(info.GetPubKey().Address())

s.T().Log("expect 404 error for address without delegations")
res, statusCode, err := getRequest(fmt.Sprintf("%s/cosmos/staking/v1beta1/delegations/%s", val.APIAddress, newAddr.String()))
s.Require().NoError(err)
s.Require().Contains(string(res), "\"code\": 5")
s.Require().Equal(404, statusCode)
}

func getRequest(url string) ([]byte, int, error) {
res, err := http.Get(url) // nolint:gosec
body, err := ioutil.ReadAll(res.Body)
if err != nil {
return nil, res.StatusCode, err
}

if err = res.Body.Close(); err != nil {
return nil, res.StatusCode, err
}

return body, res.StatusCode, nil
}

func (s *IntegrationTestSuite) TestQueryDelegatorDelegationsGRPC() {
val := s.network.Validators[0]
baseURL := val.APIAddress
Expand Down

0 comments on commit 636e659

Please sign in to comment.