feat!: support debug trace QueryResult (#9576)
<!-- The default pull request template is for types feat, fix, or refactor. For other templates, add one of the following parameters to the url: - template=docs.md - template=other.md --> ## Description To let abci query response include more detailed error message with node started with `--trace`. <!-- Add a description of the changes that this PR introduces and the files that are the most critical to review. --> --- ### Author Checklist *All items are required. Please add a note to the item if the item is not applicable and please add links to any relevant follow up issues.* I have... - [x] included the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title - [ ] added `!` to the type prefix if API or client breaking change - [x] targeted the correct branch (see [PR Targeting](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#pr-targeting)) - [ ] provided a link to the relevant issue or specification - [x] followed the guidelines for [building modules](https://github.com/cosmos/cosmos-sdk/blob/master/docs/building-modules) - [ ] included the necessary unit and integration [tests](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#testing) - [x] added a changelog entry to `CHANGELOG.md` - [ ] included comments for [documenting Go code](https://blog.golang.org/godoc) - [ ] updated the relevant documentation or specification - [x] reviewed "Files changed" and left comments if necessary - [ ] confirmed all CI checks have passed ### Reviewers Checklist *All items are required. Please add a note if the item is not applicable and please add your handle next to the items reviewed if you only reviewed selected items.* I have... - [ ] confirmed the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title - [ ] confirmed `!` in the type prefix if API or client breaking change - [ ] confirmed all author checklist items have been addressed - [ ] reviewed state machine logic - [ ] reviewed API design and naming - [ ] reviewed documentation is accurate - [ ] reviewed tests and test coverage - [ ] manually tested (if applicable)
This commit is contained in:
parent
6888de1d86
commit
e4f2fa0423
|
@ -41,6 +41,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
|
|||
|
||||
* [\#9533](https://github.com/cosmos/cosmos-sdk/pull/9533) Added a new gRPC method, `DenomOwners`, in `x/bank` to query for all account holders of a specific denomination.
|
||||
* (bank) [\#9618](https://github.com/cosmos/cosmos-sdk/pull/9618) Update bank.Metadata: add URI and URIHash attributes.
|
||||
* [\#9576](https://github.com/cosmos/cosmos-sdk/pull/9576) Add debug error message to query result when enabled
|
||||
|
||||
### API Breaking Changes
|
||||
|
||||
|
|
|
@ -405,7 +405,7 @@ func (app *BaseApp) Query(req abci.RequestQuery) (res abci.ResponseQuery) {
|
|||
// ref: https://github.com/cosmos/cosmos-sdk/pull/8039
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
res = sdkerrors.QueryResult(sdkerrors.Wrapf(sdkerrors.ErrPanic, "%v", r))
|
||||
res = sdkerrors.QueryResult(sdkerrors.Wrapf(sdkerrors.ErrPanic, "%v", r), app.trace)
|
||||
}
|
||||
}()
|
||||
|
||||
|
@ -422,7 +422,7 @@ func (app *BaseApp) Query(req abci.RequestQuery) (res abci.ResponseQuery) {
|
|||
|
||||
path := splitPath(req.Path)
|
||||
if len(path) == 0 {
|
||||
sdkerrors.QueryResult(sdkerrors.Wrap(sdkerrors.ErrUnknownRequest, "no query path provided"))
|
||||
sdkerrors.QueryResult(sdkerrors.Wrap(sdkerrors.ErrUnknownRequest, "no query path provided"), app.trace)
|
||||
}
|
||||
|
||||
switch path[0] {
|
||||
|
@ -440,7 +440,7 @@ func (app *BaseApp) Query(req abci.RequestQuery) (res abci.ResponseQuery) {
|
|||
return handleQueryCustom(app, path, req)
|
||||
}
|
||||
|
||||
return sdkerrors.QueryResult(sdkerrors.Wrap(sdkerrors.ErrUnknownRequest, "unknown query path"))
|
||||
return sdkerrors.QueryResult(sdkerrors.Wrap(sdkerrors.ErrUnknownRequest, "unknown query path"), app.trace)
|
||||
}
|
||||
|
||||
// ListSnapshots implements the ABCI interface. It delegates to app.snapshotManager if set.
|
||||
|
@ -570,12 +570,12 @@ func (app *BaseApp) ApplySnapshotChunk(req abci.RequestApplySnapshotChunk) abci.
|
|||
func (app *BaseApp) handleQueryGRPC(handler GRPCQueryHandler, req abci.RequestQuery) abci.ResponseQuery {
|
||||
ctx, err := app.createQueryContext(req.Height, req.Prove)
|
||||
if err != nil {
|
||||
return sdkerrors.QueryResult(err)
|
||||
return sdkerrors.QueryResult(err, app.trace)
|
||||
}
|
||||
|
||||
res, err := handler(ctx, req)
|
||||
if err != nil {
|
||||
res = sdkerrors.QueryResult(gRPCErrorToSDKError(err))
|
||||
res = sdkerrors.QueryResult(gRPCErrorToSDKError(err), app.trace)
|
||||
res.Height = req.Height
|
||||
return res
|
||||
}
|
||||
|
@ -746,7 +746,7 @@ func handleQueryApp(app *BaseApp, path []string, req abci.RequestQuery) abci.Res
|
|||
|
||||
gInfo, res, err := app.Simulate(txBytes)
|
||||
if err != nil {
|
||||
return sdkerrors.QueryResult(sdkerrors.Wrap(err, "failed to simulate tx"))
|
||||
return sdkerrors.QueryResult(sdkerrors.Wrap(err, "failed to simulate tx"), app.trace)
|
||||
}
|
||||
|
||||
simRes := &sdk.SimulationResponse{
|
||||
|
@ -756,7 +756,7 @@ func handleQueryApp(app *BaseApp, path []string, req abci.RequestQuery) abci.Res
|
|||
|
||||
bz, err := codec.ProtoMarshalJSON(simRes, app.interfaceRegistry)
|
||||
if err != nil {
|
||||
return sdkerrors.QueryResult(sdkerrors.Wrap(err, "failed to JSON encode simulation response"))
|
||||
return sdkerrors.QueryResult(sdkerrors.Wrap(err, "failed to JSON encode simulation response"), app.trace)
|
||||
}
|
||||
|
||||
return abci.ResponseQuery{
|
||||
|
@ -773,7 +773,7 @@ func handleQueryApp(app *BaseApp, path []string, req abci.RequestQuery) abci.Res
|
|||
}
|
||||
|
||||
default:
|
||||
return sdkerrors.QueryResult(sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unknown query: %s", path))
|
||||
return sdkerrors.QueryResult(sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unknown query: %s", path), app.trace)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -781,15 +781,14 @@ func handleQueryApp(app *BaseApp, path []string, req abci.RequestQuery) abci.Res
|
|||
sdkerrors.Wrap(
|
||||
sdkerrors.ErrUnknownRequest,
|
||||
"expected second parameter to be either 'simulate' or 'version', neither was present",
|
||||
),
|
||||
)
|
||||
), app.trace)
|
||||
}
|
||||
|
||||
func handleQueryStore(app *BaseApp, path []string, req abci.RequestQuery) abci.ResponseQuery {
|
||||
// "/store" prefix for store queries
|
||||
queryable, ok := app.cms.(sdk.Queryable)
|
||||
if !ok {
|
||||
return sdkerrors.QueryResult(sdkerrors.Wrap(sdkerrors.ErrUnknownRequest, "multistore doesn't support queries"))
|
||||
return sdkerrors.QueryResult(sdkerrors.Wrap(sdkerrors.ErrUnknownRequest, "multistore doesn't support queries"), app.trace)
|
||||
}
|
||||
|
||||
req.Path = "/" + strings.Join(path[1:], "/")
|
||||
|
@ -799,8 +798,7 @@ func handleQueryStore(app *BaseApp, path []string, req abci.RequestQuery) abci.R
|
|||
sdkerrors.Wrap(
|
||||
sdkerrors.ErrInvalidRequest,
|
||||
"cannot query with proof when height <= 1; please provide a valid height",
|
||||
),
|
||||
)
|
||||
), app.trace)
|
||||
}
|
||||
|
||||
resp := queryable.Query(req)
|
||||
|
@ -815,8 +813,7 @@ func handleQueryP2P(app *BaseApp, path []string) abci.ResponseQuery {
|
|||
return sdkerrors.QueryResult(
|
||||
sdkerrors.Wrap(
|
||||
sdkerrors.ErrUnknownRequest, "path should be p2p filter <addr|id> <parameter>",
|
||||
),
|
||||
)
|
||||
), app.trace)
|
||||
}
|
||||
|
||||
var resp abci.ResponseQuery
|
||||
|
@ -833,7 +830,7 @@ func handleQueryP2P(app *BaseApp, path []string) abci.ResponseQuery {
|
|||
}
|
||||
|
||||
default:
|
||||
resp = sdkerrors.QueryResult(sdkerrors.Wrap(sdkerrors.ErrUnknownRequest, "expected second parameter to be 'filter'"))
|
||||
resp = sdkerrors.QueryResult(sdkerrors.Wrap(sdkerrors.ErrUnknownRequest, "expected second parameter to be 'filter'"), app.trace)
|
||||
}
|
||||
|
||||
return resp
|
||||
|
@ -846,17 +843,17 @@ func handleQueryCustom(app *BaseApp, path []string, req abci.RequestQuery) abci.
|
|||
// The QueryRouter routes using path[1]. For example, in the path
|
||||
// "custom/gov/proposal", QueryRouter routes using "gov".
|
||||
if len(path) < 2 || path[1] == "" {
|
||||
return sdkerrors.QueryResult(sdkerrors.Wrap(sdkerrors.ErrUnknownRequest, "no route for custom query specified"))
|
||||
return sdkerrors.QueryResult(sdkerrors.Wrap(sdkerrors.ErrUnknownRequest, "no route for custom query specified"), app.trace)
|
||||
}
|
||||
|
||||
querier := app.queryRouter.Route(path[1])
|
||||
if querier == nil {
|
||||
return sdkerrors.QueryResult(sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "no custom querier found for route %s", path[1]))
|
||||
return sdkerrors.QueryResult(sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "no custom querier found for route %s", path[1]), app.trace)
|
||||
}
|
||||
|
||||
ctx, err := app.createQueryContext(req.Height, req.Prove)
|
||||
if err != nil {
|
||||
return sdkerrors.QueryResult(err)
|
||||
return sdkerrors.QueryResult(err, app.trace)
|
||||
}
|
||||
|
||||
// Passes the rest of the path as an argument to the querier.
|
||||
|
@ -865,7 +862,7 @@ func handleQueryCustom(app *BaseApp, path []string, req abci.RequestQuery) abci.
|
|||
// []string{"proposal", "test"} as the path.
|
||||
resBytes, err := querier(ctx, path[2:], req)
|
||||
if err != nil {
|
||||
res := sdkerrors.QueryResult(err)
|
||||
res := sdkerrors.QueryResult(err, app.trace)
|
||||
res.Height = req.Height
|
||||
return res
|
||||
}
|
||||
|
|
|
@ -279,7 +279,7 @@ func (st *Store) Query(req abci.RequestQuery) (res abci.ResponseQuery) {
|
|||
defer telemetry.MeasureSince(time.Now(), "store", "iavl", "query")
|
||||
|
||||
if len(req.Data) == 0 {
|
||||
return sdkerrors.QueryResult(sdkerrors.Wrap(sdkerrors.ErrTxDecode, "query cannot be zero length"))
|
||||
return sdkerrors.QueryResult(sdkerrors.Wrap(sdkerrors.ErrTxDecode, "query cannot be zero length"), false)
|
||||
}
|
||||
|
||||
tree := st.tree
|
||||
|
@ -339,7 +339,7 @@ func (st *Store) Query(req abci.RequestQuery) (res abci.ResponseQuery) {
|
|||
res.Value = bz
|
||||
|
||||
default:
|
||||
return sdkerrors.QueryResult(sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unexpected query path: %v", req.Path))
|
||||
return sdkerrors.QueryResult(sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unexpected query path: %v", req.Path), false)
|
||||
}
|
||||
|
||||
return res
|
||||
|
|
|
@ -529,17 +529,17 @@ func (rs *Store) Query(req abci.RequestQuery) abci.ResponseQuery {
|
|||
path := req.Path
|
||||
storeName, subpath, err := parsePath(path)
|
||||
if err != nil {
|
||||
return sdkerrors.QueryResult(err)
|
||||
return sdkerrors.QueryResult(err, false)
|
||||
}
|
||||
|
||||
store := rs.getStoreByName(storeName)
|
||||
if store == nil {
|
||||
return sdkerrors.QueryResult(sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "no such store: %s", storeName))
|
||||
return sdkerrors.QueryResult(sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "no such store: %s", storeName), false)
|
||||
}
|
||||
|
||||
queryable, ok := store.(types.Queryable)
|
||||
if !ok {
|
||||
return sdkerrors.QueryResult(sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "store %s (type %T) doesn't support queries", storeName, store))
|
||||
return sdkerrors.QueryResult(sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "store %s (type %T) doesn't support queries", storeName, store), false)
|
||||
}
|
||||
|
||||
// trim the path and make the query
|
||||
|
@ -551,7 +551,7 @@ func (rs *Store) Query(req abci.RequestQuery) abci.ResponseQuery {
|
|||
}
|
||||
|
||||
if res.ProofOps == nil || len(res.ProofOps.Ops) == 0 {
|
||||
return sdkerrors.QueryResult(sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "proof is unexpectedly empty; ensure height has not been pruned"))
|
||||
return sdkerrors.QueryResult(sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "proof is unexpectedly empty; ensure height has not been pruned"), false)
|
||||
}
|
||||
|
||||
// If the request's height is the latest height we've committed, then utilize
|
||||
|
@ -564,7 +564,7 @@ func (rs *Store) Query(req abci.RequestQuery) abci.ResponseQuery {
|
|||
} else {
|
||||
commitInfo, err = getCommitInfo(rs.db, res.Height)
|
||||
if err != nil {
|
||||
return sdkerrors.QueryResult(err)
|
||||
return sdkerrors.QueryResult(err, false)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -67,8 +67,8 @@ func ResponseDeliverTx(err error, gw, gu uint64, debug bool) abci.ResponseDelive
|
|||
|
||||
// QueryResult returns a ResponseQuery from an error. It will try to parse ABCI
|
||||
// info from the error.
|
||||
func QueryResult(err error) abci.ResponseQuery {
|
||||
space, code, log := ABCIInfo(err, false)
|
||||
func QueryResult(err error, debug bool) abci.ResponseQuery {
|
||||
space, code, log := ABCIInfo(err, debug)
|
||||
return abci.ResponseQuery{
|
||||
Codespace: space,
|
||||
Code: code,
|
||||
|
|
Loading…
Reference in New Issue