fix: grpc-gateway error codes (#9015)

* 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>
This commit is contained in:
MD Aleem 2021-03-29 19:12:43 +05:30 committed by GitHub
parent 37a8c7b9d3
commit 636e6598b9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 52 additions and 3 deletions

View File

@ -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

View File

@ -6,6 +6,8 @@ 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"
@ -13,6 +15,7 @@ import (
"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
@ -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
@ -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.

View File

@ -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"
@ -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